简体   繁体   English

MongoDB Spring Data Repository - 缓存方法

[英]MongoDB Spring Data Repository - Cache methods

I need to have calls to MongoDB cached using spring @Cacheable annotation: 我需要使用spring @Cacheable注释调用MongoDB缓存:

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

Unfortunately, annotating any method in the interface with @Cacheable causes the following exception: 不幸的是,使用@Cacheable注释接口中的任何方法都会导致以下异常:

Nov 22, 2014 7:11:06 PM org.apache.catalina.core.ApplicationContext log SEVERE: StandardWrapper.Throwable org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'example': Injection of autowired dependencies failed; 2014年11月22日下午7:11:06 org.apache.catalina.core.ApplicationContext log SEVERE:StandardWrapper.Throwable org.springframework.beans.factory.BeanCreationException:创建名为'example'的bean时出错:自动连接依赖项的注入失败; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.example.repositories.mongodb.SiteRepository com.example.siteRepo; 嵌套异常是org.springframework.beans.factory.BeanCreationException:无法自动装配字段:com.example.repositories.mongodb.SiteRepository com.example.siteRepo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'siteRepository': Post-processing of FactoryBean's singleton object failed; 嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'siteRepository'的bean时出错:FactoryBean的单例对象的后处理失败; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy92]: Common causes of this problem include using a final class or a non-visible class; 嵌套异常是org.springframework.aop.framework.AopConfigException:无法生成类[class com.sun.proxy。$ Proxy92]的CGLIB子类:此问题的常见原因包括使用最终类或不可见类; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy92 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1147) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(Abstract 嵌套异常是java.lang.IllegalArgumentException:无法在org.springframework.beans的org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)中继承最终类类com.sun.proxy。$ Proxy92。在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)上的factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1147)在Org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:293)的org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)处的AbstractAutowireCapableBeanFactory.java:458 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(摘要 BeanFactory.java:290) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:633) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:602) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665) at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:521) at org.springframework.web.servlet.FrameworkServlet.init BeanFactory.java:290)org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:633)at org位于org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet)的org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)中的.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) .java:651)org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:602)位于org.springframework.web的org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)。 servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:521)位于org.springframework.web.servlet.FrameworkServlet.init ServletBean(FrameworkServlet.java:462) at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136) at javax.servlet.GenericServlet.init(GenericServlet.java:160) at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1189) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1103) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1010) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4935) at org.apache.catalina.core.StandardContext$3.call(StandardContext.java:5262) at org.apache.catalina.core.StandardContext$3.call(StandardContext.java:5257) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.ex 位于org.apache.catalina.core的javax.servlet.GenericServlet.init(GenericServlet.java:160)的org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)中的ServletBean(FrameworkServlet.java:462) .standardWrapper.initServlet(StandardWrapper.java:1189)位于org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1103)的org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1010)at at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4935)org.apache.catalina.core.StandardContext $ 3.call(StandardContext.java:5262)at org.apache.catalina.core.StandardContext $ 3。调用(StandardContext.java:5257)java.util.concurrent.TutureTask.run(未知来源)java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源)java.util.concurrent.ThreadPoolExecutor $ Worker.run(未知)来自java.lang.Thread.run(未知来源)引起:org.springframework.beans.factory.BeanCreationException:无法自动装配字段:com.ex ample.repositories.mongodb.SiteRepository com.example.siteRepo; ample.repositories.mongodb.SiteRepository com.example.siteRepo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'siteRepository': Post-processing of FactoryBean's singleton object failed; 嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'siteRepository'的bean时出错:FactoryBean的单例对象的后处理失败; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy92]: Common causes of this problem include using a final class or a non-visible class; 嵌套异常是org.springframework.aop.framework.AopConfigException:无法生成类[class com.sun.proxy。$ Proxy92]的CGLIB子类:此问题的常见原因包括使用最终类或不可见类; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy92 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:517) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286) ... 27 more Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'siteRepository': Post-processing of FactoryBean's singleton object failed; 嵌套异常是java.lang.IllegalArgumentException:无法在org.springframework的org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:517)中继承最终类com.sun.proxy。$ Proxy92。 beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)... 27更多引起:org.springframework.beans .factory.BeanCreationException:创建名为'siteRepository'的bean时出错:FactoryBean的单例对象的后处理失败; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy92]: Common causes of this problem include using a final class or a non-visible class; 嵌套异常是org.springframework.aop.framework.AopConfigException:无法生成类[class com.sun.proxy。$ Proxy92]的CGLIB子类:此问题的常见原因包括使用最终类或不可见类; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy92 at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:115) at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1465) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:304) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191) at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:917) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:860) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:775) at org.springframework.beans.factory 嵌套异常是java.lang.IllegalArgumentException:无法在org.springframework.beans的org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:115)中继承最终类com.sun.proxy。$ Proxy92。 factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1465)org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:304)at 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)at org org.springframework.beans.factory上的.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:775) .annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:489) ... 29 more Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy92]: Common causes of this problem include using a final class or a non-visible class; .annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:489)... 29更多引起:org.springframework.aop.framework.AopConfigException:无法生成类的类CGLIB子类[类com.sun.proxy。$ Proxy92 ]:此问题的常见原因包括使用最终类或不可见类; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy92 at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:218) at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:477) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:409) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1656) at org.springf 嵌套异常是java.lang.IllegalArgumentException:无法在org.springframework.aop.framework的org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:218)中继承最终类类com.sun.proxy。$ Proxy92。 ProxyFactory.getProxy(ProxyFactory.java:109)org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:477)at 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 org.springf上的.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1656) ramework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:112) ... 36 more Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy92 at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:446) at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33) at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285) at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:206) ... 43 more ramework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:112)... 36更多引起:java.lang.IllegalArgumentException:无法在org.springframework下继承最终类com.sun.proxy。$ Proxy92。位于org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)的org.springframework.cglib.core.DefaultGeneratorStrategy.generate中的cglib.proxy.Enhancer.generateClass(Enhancer.java:446)(DefaultGeneratorStrategy.java: 25)org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)at org.springframework.cglib.proxy.Enhancer .create(Enhancer.java:285)org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:206)... 43更多

I am looking for a way to cache calls to DB (which are quite expensive). 我正在寻找一种缓存DB调用的方法(这是非常昂贵的)。 Any idea? 任何的想法?

From the Spring documentation on caches: 从关于缓存的Spring 文档

Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Cache* annotation, as opposed to annotating interfaces . Spring建议您只使用@Cache *注释来注释 具体类 (以及具体类的方法), 而不是注释接口 You certainly can place the @Cache* annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. 您当然可以将@Cache *注释放在接口(或接口方法)上,但这只能在您使用基于接口的代理时按预期工作。 The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies ( proxy-target-class="true") or the weaving-based aspect ( mode="aspectj"), then the caching settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a caching proxy, which would be decidedly bad. Java注释不是从接口继承的事实意味着如果您使用基于类的代理(proxy-target-class =“true”)或基于编织的方面(mode =“aspectj”),那么缓存设置是代理和编织基础设施无法识别,并且该对象不会被包装在缓存代理中,这将是非常糟糕的。

Probably your cache configuration is colliding with the way that Spring creates implementations of your repository interfaces at runtime. 可能您的缓存配置与Spring在运行时创建存储库接口实现的方式相冲突。

You could review your caching configuration to make it play nice with spring data (see here for different caching configuration options). 您可以查看缓存配置,使其与spring数据一起使用(请参阅此处了解不同的缓存配置选项)。

Or, you could do this: 或者,你可以这样做:

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);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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