MongoDB Spring Data Repository - 缓存方法

时间:2014-11-22 18:14:54

标签: java spring mongodb spring-data spring-data-mongodb

我需要使用spring @Cacheable注释缓存对MongoDB的调用:

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

不幸的是,使用@Cacheable注释接口中的任何方法都会导致以下异常:

  

2014年11月22日下午7:11:06 org.apache.catalina.core.ApplicationContext   log SEVERE:StandardWrapper.Throwable   org.springframework.beans.factory.BeanCreationException:错误   创建名称为&#39;示例&#39;:注入自动连接的依赖项   失败;嵌套异常是   org.springframework.beans.factory.BeanCreationException:不能   autowire字段:com.example.repositories.mongodb.SiteRepository   com.example.siteRepo;嵌套异常是   org.springframework.beans.factory.BeanCreationException:错误   创建名为&#39; siteRepository&#39;的bean:后处理   FactoryBean的单例对象失败;嵌套异常是   org.springframework.aop.framework.AopConfigException:不能   生成类[class com.sun.proxy。$ Proxy92]的CGLIB子类:   这个问题的常见原因包括使用最终类或   不可见的阶级;嵌套异常是   java.lang.IllegalArgumentException:不能继承最终类类   com.sun.proxy。$ Proxy92 at   org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)     在   org.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)     在   org.springframework.context.support.AbstractApplicationContext.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)at   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(未知来源)at   java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源)at   java.util.concurrent.ThreadPoolExecutor $ Worker.run(未知来源)at   java.lang.Thread.run(未知来源)引起:   org.springframework.beans.factory.BeanCreationException:不能   autowire字段:com.example.repositories.mongodb.SiteRepository   com.example.siteRepo;嵌套异常是   org.springframework.beans.factory.BeanCreationException:错误   创建名为&#39; siteRepository&#39;的bean:后处理   FactoryBean的单例对象失败;嵌套异常是   org.springframework.aop.framework.AopConfigException:不能   生成类[class com.sun.proxy。$ Proxy92]的CGLIB子类:   这个问题的常见原因包括使用最终类或   不可见的阶级;嵌套异常是   java.lang.IllegalArgumentException:不能继承最终类类   com.sun.proxy。$ Proxy92 at   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:错误   创建名为&#39; siteRepository&#39;的bean:后处理   FactoryBean的单例对象失败;嵌套异常是   org.springframework.aop.framework.AopConfigException:不能   生成类[class com.sun.proxy。$ Proxy92]的CGLIB子类:   这个问题的常见原因包括使用最终类或   不可见的阶级;嵌套异常是   java.lang.IllegalArgumentException:不能继承最终类类   com.sun.proxy。$ Proxy92 at   org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:115)     在   org.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)     在   org.springframework.beans.factory.support.DefaultListableBeanFactory.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:不能   生成类[class com.sun.proxy。$ Proxy92]的CGLIB子类:   这个问题的常见原因包括使用最终类或   不可见的阶级;嵌套异常是   java.lang.IllegalArgumentException:不能继承最终类类   com.sun.proxy。$ Proxy92 at   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)     在   org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.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:不能   子类final类com.sun.proxy。$ Proxy92 at   org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)     在   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 个答案:

答案 0 :(得分:4)

来自Spring的documentation

  

Spring建议您只注释具体类(以及方法   (具体类)与@ Cache *注释,而不是   注释界面。您当然可以放置@Cache *注释   在接口(或接口方法)上,但这只适用于您   如果您使用基于接口的代理,则会期望它。事实   Java注释不是从接口继承的意思是if   您正在使用基于类的代理(proxy-target-class =&#34; true&#34;)或   基于编织的方面(mode =&#34; aspectj&#34;),然后是缓存设置   代理和编织基础设施无法识别,以及   对象不会被包装在缓存代理中,这将是   非常糟糕。

可能您的缓存配置与Spring在运行时创建存储库接口实现的方式相冲突。

您可以查看缓存配置,使其与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);
    }

}