Как связать параметр для Cacheable-аннотации в интерфейсе - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь использовать Spring-JPA, как показано в приведенном ниже коде.

@Repository
public interface EmployeeCrud extends CrudRepository<Employee, Integer> {
    @Cacheable(cacheNames = "emp_by_last_name, key = "#lastName")
    List<Employee> findAllByLastName(@Param("lastName") String lastName);
}

Поскольку интерфейсы не имеют имен параметров (если они не скомпилированы с включенной отладочной информацией), я не могу получить данныеиз-за нижеприведенного исключения.

 java.lang.IllegalArgumentException: Null key returned for cache operation (maybe you are using named params on classes without debug info?) Builder[public abstract java.util.List EmployeeCrud.findAllByLastName(java.lang.String)] caches=[emp_by_last_name] | key='#lastName' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'
at org.springframework.cache.interceptor.CacheAspectSupport.generateKey(CacheAspectSupport.java:561)
at org.springframework.cache.interceptor.CacheAspectSupport.findCachedItem(CacheAspectSupport.java:502)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:389)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:327)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

Даже если я использую аннотацию @Param или @P, CacheOperationExpressionEvaluator не сможет ее разрешить, поскольку она использует DefaultParameterNameDiscoverer, которая внутренне использует StandardReflectionParameterNameDiscoverer иLocalVariableTableParameterNameDiscoverer.Если бы он также использовал AnnotationParameterNameDiscoverer, @Param был бы проанализирован.

Какие еще решения нам нужно, чтобы эта работа работала без включения отладочной информации компилятора или реализации интерфейса EmployeeCrud?

1 Ответ

0 голосов
/ 24 мая 2018

Легко!Без включенной отладочной информации вы можете ссылаться на параметр по позиции, например, так ...

@Cacheable(cacheNames = "emp_by_last_name, key = "#a0")
List<Employee> findAllByLastName(@Param("lastName") String lastName);

См. Справочную документацию для получения более подробной информации.

Такжепоскольку метод репозитория @Cacheable findAllByLastName(..) имеет только один аргумент, вам не нужно явно вызывать ключ для сохранения значения (т. е. возвращаемого значения метода в случае List<Employee>) в кеше("emp_by_last_name"), поскольку по умолчанию Абстракция кэша Spring использует параметры метода кэшируемого метода в качестве ключа.См. здесь .

Вам также следует помнить о том факте, что кэшированный результат (т. Е. Ключ / значение) будет представлять собой весь список объектов Employee.Элементы списка не будут кэшироваться индивидуально, если это то, что вы ищете.Если вам нужна эта возможность, обратитесь к другому сообщению, на которое я ответил более 1 раза.

Надеюсь, это поможет.

Приветствия!-John

...