简体   繁体   中英

Spring Data REST(using Spring Boot) - Hibernate Validation Localization

I am currently evaluating Spring Data REST .
I started with this simple example: link

It works out of the box. But now, in the next step, I wanted to try some validation to see how the framework reacts. So I simply annotated the Person class:

@Size(min = 2, message = "{test.error.message}")
private String firstName;

The validation itself is working, I get an error message. The message is resolved if I put a file called ValidationMessages.properties in the root of the classpath (see here why).


Now, instead of having the files in the root I wanted to place them in a subfolder (eg lang/ValidationMessages.properties ) and use Spring MessageSource instead of the default approach.

After some research I found the following question: MessageInterpolator in Spring

Unfortunately using the following bean definitions does not work:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">

  <bean id="messageSource"
            class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
      <list>
        <value>lang/ValidationMessages</value>
      </list>
    </property>
  </bean>

  <bean id="validator"
            class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="validationMessageSource" ref="messageSource"/>
  </bean>
</beans>

The corresponding dependencies inside the pom.xml (just in case):

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

Does anyone know what I am missing? Could it be due to the fact that I am not using Spring MVC but Spring Data REST? If yes, is there a way of getting this to work?

After some additional investigation (and a lot of searching) I found a solution to the issue.


PROBLEM

Hibernate does not use beans for the validator factory , thats why the LocalValidatorFactoryBean is not used.

For more details look into org.hibernate.cfg.beanvalidation.TypeSafeActivator#activate(ActivationContext activationContext)


FIRST APPROACH

You can actually specify which factory to use by using this property: javax.persistence.validation.factory

Unfortunately this can't be used (yet) inside Spring Boot's application.properties .
(see this Issue on GitHub )


SOLUTION

Using the workaround described in the linked GitHub issue works. You have to provide a configuration for Hibernate:

@Configuration
public class HibernateConfig extends HibernateJpaAutoConfiguration {

  @Autowired
  private ValidatorFactory validator;

  @Override
  protected void customizeVendorProperties(Map<String, Object>     vendorProperties) {
    super.customizeVendorProperties(vendorProperties);
    vendorProperties.put("javax.persistence.validation.factory", validator);
  }
}

Using this approach the messages get resolved correctly.

HibernateJpaAutoConfiguration can not work anymore (after sprint boot 2.10)

You can do like this if you are using Spring Boot 2.1.0+:

@Configuration
@Lazy
class SpringValidatorConfiguration {

    @Bean
    @Lazy
    public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(final Validator validator) {
        return new HibernatePropertiesCustomizer() {

            @Override
            public void customize(Map<String, Object> hibernateProperties) {
                hibernateProperties.put("javax.persistence.validation.factory", validator);
            }
        };
    }
}

The idea from Spring Boot 2.0.0 M6 - Add Hibernate Interceptor

and Spring Boot - Hibernate custom constraint doesn't inject Service

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM