【问题标题】:@Override and @Transactional annotations@Override 和 @Transactional 注释
【发布时间】:2013-07-20 07:18:59
【问题描述】:

我使用 jpa、eclispelink 和 spring 3。我有 UserDAO 接口:

  public interface UserDAO {
    public void saveUser(User user);
  }

和实现类:

@Service
@Transactional
public class UserDAOImpl implements UserDAO{

@PersistenceContext
EntityManager em;

@Override
public void saveUser(User user) {
    em.persist(user);
}


当我启动应用程序时出现错误:

HTTP Status 500 - Servlet.init() for servlet appServlet threw exception<br>
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cartController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: foo.endpoints.UserEndpoint foo.controller.CartController.userEndpoint; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userEndpoint': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: foo.dao.UserDAOImpl foo.endpoints.UserEndpoint.userDAO; nested exception is java.lang.IllegalArgumentException: Can not set foo.dao.UserDAOImpl field foo.endpoints.UserEndpoint.userDAO to com.sun.proxy.$Proxy16

org.springframework.beans.factory.BeanCreationException: Could not autowire field: foo.endpoints.UserEndpoint foo.controller.CartController.userEndpoint; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userEndpoint': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: foo.dao.UserDAOImpl foo.endpoints.UserEndpoint.userDAO; nested exception is java.lang.IllegalArgumentException: Can not set foo.dao.UserDAOImpl field foo.endpoints.UserEndpoint.userDAO to com.sun.proxy.$Proxy16


但如果我不实现接口:

 @Service
 @Transactional
 public class UserDAOImpl {
 @PersistenceContext
 EntityManager em;
  public void saveUser(User user) {
  em.persist(user);
  }


一切正常。我不明白。也许它与@Override 方法有关?谢谢

【问题讨论】:

  • 我确信问题stackoverflow.com/a/8224772/241986有一些完全相同的重复,基本上Spring的默认策略是如果类实现至少一个接口则使用JDK代理,否则使用CGLIB代理。使用 JDK 代理时,您将无法注入类,只有接口可用。
  • 顺便说一句,我认为惯例是用@Repository而不是@Service注释DAO类
  • @BorisTreukhov 正是问题所在!!我一直在寻找这些奇怪的问题

标签: spring spring-mvc jpa


【解决方案1】:

如果你为你的 bean 定义了一个接口,那么你必须注入一个接口的实例,而不是一个具体类的实例:

@Autowired
private UserDAO userDAO;

而不是

@Autowired
private UserDAOImpl userDAOImpl;

因为实际的 bean 实例是 JDK 动态代理,它实现接口并调用您的实现。它不是 UserDAOImpl 的实例。

【讨论】:

  • 我相信第二段代码应该是private UserDAOImpl userDAOImpl;吧?
  • 是的。对不起那个错误。
  • 但是如果没有接口呢? (例如,一个直接用@Component注解的辅助类)
猜你喜欢
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
  • 2012-02-02
  • 2012-05-19
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多