2012-05-26 50 views
0

我目前正在开发集成了Hibernate的Spring MVC项目。纯Spring MVC部分(DispatcherServlet +请求映射)工作正常。现在,我必须解决的问题非常奇怪:我读过“使用Hibernate进行Java持久化”,我试图以与本书中介绍的方式类似的方式设计持久层。也就是说,我设计了两个并行层次结构:一个用于实现类,另一个用于接口。Spring MVC + Hibernate DAO:无法连接bean

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

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

这里是我的问题:

  • 自动装配实现接口一个DAO类,但伸出我的抽象GenericDaoImpl类:OK
  • 自动装配我AdvertisementDaoImpl实现了AdvertisementDao接口和扩展我的抽象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;嵌套0​​例外是java.lang.IllegalArgumentException异常:无法设置 be.glimmo.service.AdvertisementService场 be.glimmo.controller.HomeController.advertisementService到 be.glimmo.dao.AdvertisementDaoImpl

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

+0

你必须告诉我们什么是你所得到的例外。 –

+2

有点偏移,但为什么generic dao实现BeanPostProcessor? –

+0

我有我的通用dao实现BeanPostProcessor,以便其持有类型化类的属性将在bean实例化时初始化。但它主要是为了测试目的,因为它绝对没有必要 – kyiu

回答

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是不存在默认情况下,你把所有的方法,从实现的接口来,但你会错过的层次结构中来自超类中的方法代理,这就是为什么你会得到这个异常。

0

经过几次更多的测试后发现问题是由我的抽象GenericDaoImpl类实现BeanPostProcessor接口引起的:出于某种原因,来自此接口的方法不仅在此bean实例化处执行,而且还在处执行每个bean处理。因为在我的BeanPostProcessor钩子方法中,我检索泛型参数化类型,当这些方法对不在我的DAO层次结构中的类执行时,它们最终会产生运行时异常(更具体地说,是ClassCastException)。

所以,要解决这个问题,我有我的GenericDaoImpl类没有实现BeanPostProcessor接口了,我感动的钩子方法的身体在空构造器。