0

我目前正在开发一个集成了 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 配置(链接到 pastebin.com):

4

2 回答 2

0

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

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

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

于 2012-05-28T12:56:26.250 回答
0

我相信你应该proxy-target-class在你的事务管理配置中使用:

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

您描述的问题的症状与Spring 事务管理(查找表 10.2)和使用 Spring 的 AOP 代理中提到的症状相匹配:

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

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

于 2012-05-27T10:27:21.773 回答