0

When I integrate Spring cache (with EHCache) and Spring validation, proxy order is not being correctly set.

I want the validation annotation to be processed BEFORE cache annotations (CacheEvict in this case) are processed.

My configuration class:

@EnableCaching( order = Ordered.LOWEST_PRECEDENCE )
@Configuration
public class CommonConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() throws IOException {

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor( LocalValidatorFactoryBean validator ) {
        MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
        methodValidationPostProcessor.setValidator( validator );
        methodValidationPostProcessor.setOrder( Ordered.LOWEST_PRECEDENCE- 1 );
        return methodValidationPostProcessor;
    }

    @Bean
    public EhCacheCacheManager cacheManager() {
        EhCacheCacheManager cacheManager = new EhCacheCacheManager();
        cacheManager.setCacheManager( ehCacheManager().getObject() );
        return cacheManager;
    }

    @Bean
    public EhCacheManagerFactoryBean ehCacheManager() {
        EhCacheManagerFactoryBean ehcache = new EhCacheManagerFactoryBean();
        ehcache.setConfigLocation( new ClassPathResource( "ehcache.xml" ) );
        return ehcache;
    }

}

And my related dependencies:

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.2.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.2.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.2.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>

        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.10.2</version>
        </dependency>

The interface and implementing class with the problem:

@Validated
public interface MyRepository {

    public void update(@NotNull MyEntity entity);

}


@Repository
public class MyRepositoryImpl implements MyRepository {

    @CacheEvict(cacheNames = {"entityCache"});
    public void update(MyEntity entity);
}

As it can be seen I have set order to MethodValidationPostProcessor to Orderer.LOWEST_PRECEDENCE- 1 and cache order to Ordered.LOWEST_PRECEDENCE (in @EnacbleCaching).

Is that the correct way to set proxy order?

Can be the problem be related to having validation annotation in the interface and cache annotation in the implementation?

Basa
  • 105
  • 2
  • 15
  • 1
    Yes, having the `@Validated` annotation on your interface is most likely the problem here. As you can see the `@Validated` annotation (https://github.com/spring-projects/spring-framework/blob/v4.2.6.RELEASE/spring-context/src/main/java/org/springframework/validation/annotation/Validated.java) is not `@Inherited`. And, even if it was, since you annotated your `MyRepository` interface with `@Validated`, Java would still not pick it up (see http://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Inherited.html). You must annotate `MyRepositoryImpl` with `@Validated` instead. – John Blum May 16 '16 at 17:58
  • Thank you John.I have realized that, being the way you propose the correct one, my class hierarchy does not allows me apply both filters: validation annotations are in a common interface (CommonDAO) implemented by a common superclass (abstract class CommonDAOImpl). Cache annotations must be different for each class extening the commong superclass (i.e. CustomerDAOImpl), but I cannot override constraint annotated methods (validation framework requirement). May be I should consider some refactoring... – Basa May 17 '16 at 00:35

1 Answers1

1

I managed to address this, based on the suggestions provided here, here and here (for non xml based configuration).

The main point is the order of the MethodValidationPostProcessor is just the order of the post processors, not the one of the advices, which we are after.

See the commit for the changes required to address this cache/validation issue.

jtonic
  • 609
  • 1
  • 7
  • 10