我目前正在开发一个Spring集成Hibernate的Spring MVC项目。纯Spring MVC部分(DispatcherServlet +请求映射)工作正常。现在,我必须解决的问题很奇怪:我已经阅读了“Java Persistence with Hibernate”,我试图以与本书中所解释的类似的方式设计我的持久层。也就是说,我在两个并行层次结构中设计了它:一个用于实现类,另一个用于接口。
所以,我有一个名为GenericDaoImpl的抽象类,它实现了GenericDao接口。然后我有一个名为AdvertisementDaoImpl的具体类,它扩展了GenericDaoImpl并实现了AdvertisementDao接口(扩展了GenericDao)。
然后,在服务bean(标有@Service的类)中,我将自动使用我的dao类。
这是我的问题:
我在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):
答案 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接口了,我在空构造函数中移动了钩子方法的主体。