Spring的@Repository注解无效,但@Service注解有效吗?

4
我有一个简单的名为BeaconDao的类。
    package za.co.idealize.dao.impl;
import java.util.List;
import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;
import za.co.idealize.dao.BaseDao; import za.co.idealizeit.model.Beacon;
@Service("beaconDao") public class BeaconDao extends BaseDao{
@Autowired protected BeaconDao(@Qualifier("sessionFactory") SessionFactory sessionFactory) { super(sessionFactory, Beacon.class);
}
@Transactional(readOnly = true) @SuppressWarnings("unchecked") public List findByStoreID(int storeID) { Session session = getSession();
Transaction tx = session.beginTransaction(); Query q = session.createQuery( "FROM Beacon b where b.storeId = :id"); q.setParameter("id",storeID);
List beacon = q.list();
tx.commit(); return beacon; }
@SuppressWarnings("unchecked") public List findByUUID(String UUID) { Session session = getSession();
Transaction tx = session.beginTransaction();
List beacon = session.createQuery( "FROM Beacon where Beacon.Uuid = " + UUID).list(); tx.commit(); return beacon; }
}

每当我使用带有@Repository标记的beaconDAO启动应用程序时,应用程序会返回以下堆栈跟踪:

    SEVERE: Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0' defined in class path resource [application-context.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beaconJsonController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public za.co.idealize.dao.impl.BeaconDao za.co.idealize.controller.BeaconJsonController.beaconDao; nested exception is java.lang.IllegalArgumentException: Can not set za.co.idealize.dao.impl.BeaconDao field za.co.idealize.controller.BeaconJsonController.beaconDao to com.sun.proxy.$Proxy30
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4961)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5455)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
        at java.lang.Thread.run(Thread.java:695)
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beaconJsonController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public za.co.idealize.dao.impl.BeaconDao za.co.idealize.controller.BeaconJsonController.beaconDao; nested exception is java.lang.IllegalArgumentException: Can not set za.co.idealize.dao.impl.BeaconDao field za.co.idealize.controller.BeaconJsonController.beaconDao to com.sun.proxy.$Proxy30
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:973)
        at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:287)
        at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:266)
        at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.detectHandlers(AbstractDetectingUrlHandlerMapping.java:82)
        at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.initApplicationContext(AbstractDetectingUrlHandlerMapping.java:58)
        at org.springframework.context.support.ApplicationObjectSupport.initApplicationContext(ApplicationObjectSupport.java:120)
        at org.springframework.web.context.support.WebApplicationObjectSupport.initApplicationContext(WebApplicationObjectSupport.java:73)
        at org.springframework.context.support.ApplicationObjectSupport.setApplicationContext(ApplicationObjectSupport.java:74)
        at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:119)
        at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:94)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:407)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1545)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
        ... 21 more
    Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public za.co.idealize.dao.impl.BeaconDao za.co.idealize.controller.BeaconJsonController.beaconDao; nested exception is java.lang.IllegalArgumentException: Can not set za.co.idealize.dao.impl.BeaconDao field za.co.idealize.controller.BeaconJsonController.beaconDao to com.sun.proxy.$Proxy30
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
        ... 41 more
    Caused by: java.lang.IllegalArgumentException: Can not set za.co.idealize.dao.impl.BeaconDao field za.co.idealize.controller.BeaconJsonController.beaconDao to com.sun.proxy.$Proxy30
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
        at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
        at java.lang.reflect.Field.set(Field.java:657)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:504)
        ... 43 more
    Jun 24, 2014 1:30:46 AM org.apache.catalina.core.StandardContext listenerStart
    SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0' defined in class path resource [application-context.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beaconJsonController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public za.co.idealize.dao.impl.BeaconDao za.co.idealize.controller.BeaconJsonController.beaconDao; nested exception is java.lang.IllegalArgumentException: Can not set za.co.idealize.dao.impl.BeaconDao field za.co.idealize.controller.BeaconJsonController.beaconDao to com.sun.proxy.$Proxy30
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4961)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5455)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
        at java.lang.Thread.run(Thread.java:695)
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beaconJsonController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public za.co.idealize.dao.impl.BeaconDao za.co.idealize.controller.BeaconJsonController.beaconDao; nested exception is java.lang.IllegalArgumentException: Can not set za.co.idealize.dao.impl.BeaconDao field za.co.idealize.controller.BeaconJsonController.beaconDao to com.sun.proxy.$Proxy30
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:973)
        at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:287)
        at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:266)
        at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.detectHandlers(AbstractDetectingUrlHandlerMapping.java:82)
        at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.initApplicationContext(AbstractDetectingUrlHandlerMapping.java:58)
        at org.springframework.context.support.ApplicationObjectSupport.initApplicationContext(ApplicationObjectSupport.java:120)
        at org.springframework.web.context.support.WebApplicationObjectSupport.initApplicationContext(WebApplicationObjectSupport.java:73)
        at org.springframework.context.support.ApplicationObjectSupport.setApplicationContext(ApplicationObjectSupport.java:74)
        at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:119)
        at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:94)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:407)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1545)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
        ... 21 more
    Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public za.co.idealize.dao.impl.BeaconDao za.co.idealize.controller.BeaconJsonController.beaconDao; nested exception is java.lang.IllegalArgumentException: Can not set za.co.idealize.dao.impl.BeaconDao field za.co.idealize.controller.BeaconJsonController.beaconDao to com.sun.proxy.$Proxy30
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
        ... 41 more
    Caused by: java.lang.IllegalArgumentException: Can not set za.co.idealize.dao.impl.BeaconDao field za.co.idealize.controller.BeaconJsonController.beaconDao to com.sun.proxy.$Proxy30
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
        at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
        at java.lang.reflect.Field.set(Field.java:657)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:504)
        ... 43 more

然而,当我使用@Service或@Component标记beaconDao时,一切都能够正常工作。有人能看出问题吗?


5
你确定你正在使用org.springframework.stereotype.Repository吗?能否发布带有@Repository注解的配置和代码(包括导入)? - Kevin Bowersox
@KevinBowersox 我的直觉也是如此。楼主请注意,这里的根错误是“无法将za.co.idealize.dao.impl.BeaconDao字段设置为com.sun.proxy.$Proxy30”。 - drew moore
你的应用程序中使用AOP吗? - davioooh
非常感谢您的回复。虽然我没有使用AOP,但我发现下面的答案很有帮助。我仍然不清楚为什么“@Repository”注释在没有使用接口的情况下无法工作,但是“@Service”和“@Component”注释允许您使用具体类。 - Moejoejoejoe
1个回答

6
问题完全在于此外: za.co.idealize.controller.BeaconJsonController 的单例中使用了 JDK 代理,因此 Spring 无法设置 beaconDao 字段。您已将 BeaconJsonController.beaconDao 声明为 BeaconDao 类,而应该使用某种接口。我猜测您的 BeaconDao 类层次结构类似于 BeaconDao -> BaseDao -> ISomeDao,其中 ISomeDao 是一个接口。请将 BeaconJsonController 中的声明更改为:
private BeaconDao beaconDao; 

to

private ISomeDao beaconDao;

如果必须使用限定符,请使用它。问题在于,Spring将为ISomeDao接口创建代理,而不是BeaconDao,然后您尝试将ISomeDao代理分配给BeaconDao字段,这会导致类转换异常。


嘿,感谢您的回答。当我使用接口时,它确实起作用。但是,我仍然不清楚为什么 '@Service' 和 '@Component' 可以与具体类一起使用,而 '@Repository' 则需要与接口一起使用。我原本认为 '@Service' 和 '@Component' 只是 '@Component' 注释的子注释。 - Moejoejoejoe
@dimoniy,你好,你的回答解决了我的项目中的一个大问题。非常感谢你。但是如果你能够解释一下“你已经将BeaconJsonController.beaconDao声明为BeaconDao类,而实际应该使用某种接口”,那就太好了。为什么我需要使用接口而不是类本身? - Sajib Acharya
1
Spring使用两种代理:JDK代理和CGLIB代理。JDK代理仅适用于接口,因此当您通过Spring创建任何类型的对象并使用JDK代理时,Spring只能识别和连接接口。 - dimoniy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接