2014-11-22 5 views
3

Мне нужно, чтобы звонить в MongoDB кешированных с помощью пружинного @Cacheable аннотации:MongoDB Spring Data Repository - методы Cache

public interface SiteRepository extends PagingAndSortingRepository<Site, String>{ 
    @Cacheable 
    List<Site> findByStatus(Site.Status status); 
} 

К сожалению, аннотированием любой метод в интерфейсе с @Cacheable вызывает следующее исключение:

22 ноября 2014 7:11:06 PM org.apache.catalina.core.ApplicationContext журнала СИЛЬНЫЙ: StandardWrapper.Throwable org.springframework.beans.factory.BeanCreationException: Ошибка создания компонента с именем 'например' : Впрыскивание автоуведомленных зависимостей не удалось; вложенное исключение - org.springframework.beans.factory.BeanCreationException: не может поле autowire: com.example.repositories.mongodb.SiteRepository com.example.siteRepo; вложенное исключение - org.springframework.beans.factory.BeanCreationException: ошибка создание bean-компонента с именем 'siteRepository': постобработка объекта Singleton объекта FactoryBean не удалась; вложенное исключение - org.springframework.aop.framework.AopConfigException: не удалось создать подкласс класса CGLIB класса [класс com.sun.proxy. $ Proxy92]: . Общие причины этой проблемы включают использование конечного класса или , видимый класс; вложенное исключение java.lang.IllegalArgumentException: Невозможно создать подкласс окончательный класс класса com.sun.proxy $ Proxy92 на org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues ​​(AutowiredAnnotationBeanPostProcessor.java:289) в орг. .springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean (AbstractAutowireCapableBeanFactory.java:1147) на org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:519) на org.springframework.beans .factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:458) в org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject (AbstractBeanFactory.java:293) в org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:223) в org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:290) на org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:191) на org.springframework. beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:633) at org.springframework.context.support.AbstractApplicationCo ntext.finishBeanFactoryInitialization (AbstractApplicationContext.java:932) на org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:479) на org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext (FrameworkServlet.java: 651) на org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext (FrameworkServlet.java:602) на org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext (FrameworkServlet.java:665) на org.springframework .web.servlet.FrameworkServlet.initWebApplicationContext (FrameworkServlet.Java: 521) на org.springframework.web.servlet.FrameworkServlet.initServletBean (FrameworkServlet.java:462) на org.springframework.web.servlet.HttpServletBean.init (HttpServletBean.java:136) в javax. servlet.GenericServlet.init (GenericServlet.java:160) при org.apache.catalina.core.StandardWrapper.initServlet (StandardWrapper.java:1189) на org.apache.catalina.core.StandardWrapper.loadServlet (StandardWrapper.java : 1103) на org.apache.catalina.core.StandardWrapper.load (StandardWrapper.java:1010) на org.apache.catalina.core.StandardContext.loadOnStartup (StandardContext.java:4935) т org.apache.catalina.core.StandardContext $ 3.call (StandardContext.java:5262) ​​ в org.apache.catalina.core.StandardContext $ 3.call (StandardContext.java:5257) в java.util.concurrent .FutureTask.run (Неизвестный источник) в java.util.concurrent.ThreadPoolExecutor.runWorker (Неизвестный источник) в java.util.concurrent.ThreadPoolExecutor $ Worker.run (Неизвестный источник) в java.lang.Thread.run (Неизвестный источник) Вызвано: org.springframework.beans.factory.BeanCreationException: Не удалось поле autowire: com.example.repositories.mongodb.SiteRepository com.example.siteRepo; вложенное исключение - org.springframework.beans.factory.BeanCreationException: ошибка создание bean-компонента с именем 'siteRepository': постобработка объекта Singleton объекта FactoryBean не удалась; вложенное исключение - org.springframework.aop.framework.AopConfigException: не удалось создать подкласс класса CGLIB класса [класс com.sun.proxy. $ Proxy92]: . Общие причины этой проблемы включают использование конечного класса или , видимый класс; вложенное исключение java.lang.IllegalArgumentException: Невозможно создать подкласс окончательного класса класса com.sun.proxy $ Proxy92 на org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject (AutowiredAnnotationBeanPostProcessor.java:517) в. org.springframework.beans.factory.annotation.InjectionMetadata.inject (InjectionMetadata.java:87) на org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues ​​(AutowiredAnnotationBeanPostProcessor.java:286) ... подробнее 27 Вызвано: org.springframework.beans.factory.BeanCreationException: Ошибка создание bean-компонента с именем 'siteRepository': постобработка o f Неисправность объекта Singleton объекта FactoryBean; вложенное исключение - org.springframework.aop.framework.AopConfigException: не удалось создать подкласс класса CGLIB класса [класс com.sun.proxy. $ Proxy92]: . Общие причины этой проблемы включают использование конечного класса или , видимый класс; вложенное исключение java.lang.IllegalArgumentException: Невозможно создать подкласс окончательного класса класса com.sun.proxy $ Proxy92 на org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean (FactoryBeanRegistrySupport.java:115) в орг. .springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance (AbstractBeanFactory.java:1465) на org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:304) на org.springframework.beans .factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:191) at org.springframework.beans.factory.support.DefaultListableBeanFact ory.findAutowireCandidates (DefaultListableBeanFactory.Java: 917) на org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency (DefaultListableBeanFactory.java:860) на org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency (DefaultListableBeanFactory.java:775) на org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject (AutowiredAnnotationBeanPostProcessor.java:489) ... 29 более Вызванный: org.springframework.aop.framework.AopConfigException: не удалось генерировать CGLIB подкласс класса [класс com.sun.proxy. $ Proxy92]: Общие причины этой проблемы включают использование конечного класса или no n-видимый класс; вложенное исключение java.lang.IllegalArgumentException: Невозможно создать подкласс окончательного класса класса com.sun.proxy $ Proxy92 на org.springframework.aop.framework.CglibAopProxy.getProxy (CglibAopProxy.java:218) на org.springframework. .aop.framework.ProxyFactory.getProxy (ProxyFactory.java:109) на org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy (AbstractAutoProxyCreator.java:477) на org.springframework.aop.framework.autoproxy .AbstractAutoProxyCreator.wrapIfNecessary (AbstractAutoProxyCreator.java:362) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization (AbstractAutoProxyCre ator.java:322) на org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization (AbstractAutowireCapableBeanFactory.java:409) на org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean (AbstractAutowireCapableBeanFactory.java: 1656) на org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean (FactoryBeanRegistrySupport.java:112) ... 36 более причиненном: java.lang.IllegalArgumentException: Может не подкласса конечного класса класса com.sun. прокси. $ Proxy92 на org.springframework.cglib.proxy.Enhancer.generateClass (Enhancer.java:446) at 44 +44516410617451515053691368888 org.springframework.cglib.transform.TransformingClassGenerator.generateClass (TransformingClassGenerator.java:33) на org.springframework.cglib.core.DefaultGeneratorStrategy.generate (DefaultGeneratorStrategy.java:25) на org.springframework.cglib.core .AbstractClassGenerator.create (AbstractClassGenerator.java:216) на org.springframework.cglib.proxy.Enhancer.createHelper (Enhancer.java:377) в org.springframework.cglib.proxy.Enhancer.create (Enhancer.java: 285) на org.springframework.aop.framework.CglibAopProxy.getProxy (CglibAopProxy.java:206) ... 43 более

Я ищу способ кэширования вызовов в DB (что довольно дорого). Есть идеи?

ответ

1

С весны documentation на кэшей:

Spring рекомендует только аннотацию конкретные классы (и методы конкретных классов) с @ Cache * аннотацию, в отличие от аннотирования интерфейсов ,Вы, конечно, можете разместить аннотацию @ Cache * на интерфейсе (или на методе интерфейса), но это работает только тогда, когда вы ожидаете этого, если используете интерфейсные прокси. Факт о том, что аннотации Java не наследуются от интерфейсов, означает, что если вы используете прокси-классы на основе класса (proxy-target-class = "true") или аспекте ткачества (mode = "aspectj"), тогда настройки кэширования - , которые не распознаются инфраструктурой проксирования и переплетения, а объект не будет завернут в кеширующий прокси, который будет явно плохим.

Возможно, ваша конфигурация кэша сталкивается с тем, как Spring создает реализации интерфейсов репозитория во время выполнения.

Вы можете просмотреть конфигурацию кэширования, чтобы она играла хорошо с данными о пружинах (см. here для разных параметров конфигурации кеширования).

Или вы могли бы сделать это:

public interface SiteRepository extends PagingAndSortingRepository<Site, String>{ 
    List<Site> findByStatus(Site.Status status); 
} 

@Service 
public class CachedSiteService { 

    @Autowired 
    private SiteRepository siteRepository; 

    @Cacheable("sites") 
    List<Site> findByStatus(Site.Status status) { 
     return siteRepository.findByStatus(status); 
    } 

} 
+0

я в конечном итоге делает свой второй вариант через службу и кэширование его. Я считаю это довольно громоздким, так как вам нужен дополнительный сервис. Я ожидал, что люди Spring также включат @Cacheable в репозиториях. Спасибо за ответ! – checklist

+0

Это также относится к методам контроллера? Если я добавлю @Cacheable методу, который возвращает список объектов, будет ли список кэшироваться? Как обеспечить привязку списка к идентификатору? – AlexCon

Смежные вопросы