【问题标题】:Spring MVC + Hibernate DAOs : unable to wire beansSpring MVC + Hibernate DAO:无法连接 bean
【发布时间】:2012-06-01 20:49:28
【问题描述】:

我目前正在开发一个集成了 Hibernate 的 Spring MVC 项目。纯 Spring MVC 部分(DispatcherServlet + 请求映射)工作正常。现在,我必须处理的问题很奇怪:我已经阅读了“Java Persistence with Hibernate”,并且我正在尝试以与书中解释的方式相似的方式设计我的持久层。也就是说,我在两个并行的层次结构中设计了它:一个用于实现类,另一个用于接口。

所以,我有一个名为 GenericDaoImpl 的抽象类,它实现了 GenericDao 接口。然后我有一个名为 AdvertisementDaoImpl 的具体类,它扩展了 GenericDaoImpl 并实现了 AdvertisementDao 接口(它扩展了 GenericDao)。

然后,在服务 bean(标有 @Service 的类)中,我将自动装配我的 dao 类。

这是我的问题:

  • 自动装配实现接口但扩展我的抽象 GenericDaoImpl 类的 DAO 类:好的
  • 自动装配实现 AdvertisementDao 接口并扩展我的抽象 GenericDaoImpl 类的 AdvertisementDaoImpl:导致 bean 初始化异常。

我在 DAO 层次结构顶部的抽象类处理常见 CRUD 方法的所有样板代码。所以,我绝对想保留它。

有人对此有解释吗?

下面是一段代码:

public abstract class GenericDaoImpl <T, ID extends Serializable> implements BeanPostProcessor, GenericDao<T, ID>{
    @Autowired(required=true)
    private SessionFactory sessionFactory;
    private Session currentSession;
    private Class<T> persistentClass;

...
}


@Repository
public class AdvertisementDaoImpl extends GenericDaoImpl<Advertisement, Long> implements AdvertisementDao {

...


    public List<Advertisement> listAdvertisementByType(AdvertisementType advertisementType, Class<? extends Good> type) {
        return null;
    }

}

@Service
public class AdvertisementServiceImpl implements AdvertisementService{
    @Autowired(required=false)
    private AdvertisementDao advertisementDao;

    public List<Advertisement> listAllAdvertisements() {

        return null;
    }

}

这是堆栈跟踪中最相关的部分(至少,我猜是这样):

嵌套异常是 org.springframework.beans.factory.BeanCreationException:不能 自动装配字段:be.glimmo.service.AdvertisementService be.glimmo.controller.HomeController.advertisementService;嵌套的 异常是 java.lang.IllegalArgumentException: 无法设置 be.glimmo.service.AdvertisementService 字段 be.glimmo.controller.HomeController.advertisementService 到 be.glimmo.dao.AdvertisementDaoImpl

这是我的Spring configuration(链接到 pastebin.com):

【问题讨论】:

  • 您必须向我们准确展示您遇到的异常情况。
  • 有点离题,但为什么通用 dao 实现了 BeanPostProcessor?
  • 我让我的通用 dao 实现了 BeanPostProcessor,这样它包含类型化类的属性将在 bean 实例化时被初始化。但这主要是为了测试目的,因为绝对没有必要

标签: spring hibernate spring-mvc hibernate-generic-dao


【解决方案1】:

我认为您应该在事务管理配置中使用proxy-target-class

<tx:annotation-driven transaction-manager="transactionManagerForHibernate" 
     proxy-target-class="true" />

您描述的问题症状与Spring Transaction Management(查找表10.2)和AOP proxying with Spring中提到的症状相符:

如果要代理的目标对象至少实现一个接口 然后将使用 JDK 动态代理。所有接口 由目标类型实现的将被代理。如果目标对象 没有实现任何接口,那么将创建一个 CGLIB 代理。

因此,当默认情况下不存在 CGLIB 时,您拥有来自已实现接口的所有方法,但您将错过对来自层次结构中超类的方法的代理,这就是您在此问题上遇到异常的原因。

【讨论】:

    【解决方案2】:

    经过几次测试后,发现问题是由我的抽象 GenericDaoImpl 类实现 BeanPostProcessor 接口引起的:出于某种原因,该接口的方法不仅在此 bean 实例化时执行,而且在 每个 bean实例化

    鉴于在我的 BeanPostProcessor 挂钩方法中,我正在检索泛型参数化类型,当这些方法针对不在我的 DAO 层次结构中的类执行时,它们最终会产生运行时异常(更具体地说,ClassCastException)。

    所以,为了解决这个问题,我让我的 GenericDaoImpl 类不再实现 BeanPostProcessor 接口,并将钩子方法的主体移动到空构造函数中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 2011-01-27
      • 2010-12-07
      • 1970-01-01
      • 2013-12-24
      • 2011-05-06
      相关资源
      最近更新 更多