Spring MVC + Hibernate DAO:无法连接bean

时间:2012-05-26 17:48:06

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

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

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

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

这是我的问题:

  • 自动装配实现接口的DAO类,但扩展我的抽象GenericDaoImpl类:OK
  • 自动装配我实现AdvertisementDao接口的AdvertisementDaoImpl,扩展我的抽象GenericDaoImpl类:导致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:不能   autowire字段:be.glimmo.service.AdvertisementService   be.glimmo.controller.HomeController.advertisementService;嵌套   异常是java.lang.IllegalArgumentException:无法设置   be.glimmo.service.AdvertisementService字段   be.glimmo.controller.HomeController.advertisementService to   be.glimmo.dao.AdvertisementDaoImpl

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

2 个答案:

答案 0 :(得分:0)

我相信您应该在事务管理配置中使用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不存在时,您拥有来自已实现接口的所有方法,但是您将错过代理来自层次结构中超类的方法的代理,这就是您在此处获得异常的原因。

答案 1 :(得分:0)

经过几次测试,结果发现问题是由我的抽象GenericDaoImpl类实现BeanPostProcessor接口引起的:由于某种原因,这个接口的方法不仅在这个bean实例化中执行,而且在每个bean执行intantiation 即可。

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

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