0

我正在将一个工作项目从 Spring2+Hibernate3 升级到 Spring3+Hibernate4。由于 HibernateTemplate 和 HibernateDAOSupport 已经退役,我做了以下

之前(简化)

public List<Object> loadTable(final Class<?> cls)
{
    Session s = getSession(); // was calling the old Spring getSession
    Criteria c = s.createCriteria(cls);
    List<Object> objects = c.list();
    if (objects == null)
    {
        objects = new ArrayList<Object>();
    }
    closeSession(s);
    return objects;
}

现在(简化)

@Transactional(propagation=Propagation.REQUIRED)
public List<Object> loadTable(final Class<?> cls)
{
    Session s = sessionFactory.getCurrentSession();
    Criteria c = s.createCriteria(cls);
    List<Object> objects = c.list();
    if (objects == null)
    {
        objects = new ArrayList<Object>();
    }
    return objects;
}

我还将事务注释声明添加到 Spring XML 并从 Hibernate 属性中删除

 "hibernate.current_session_context_class", "org.hibernate.context.ThreadLocalSessionContext"

正如我在堆栈跟踪中看到的那样,@Transactional 注释似乎有效

at com.database.spring.DatabaseDAOImpl$$EnhancerByCGLIB$$7d20ef95.loadTable(<generated>)

在初始化期间,上面概述的更改似乎适用于对 loadTable 函数的一些调用,但是当它开始加载具有父级的实体时,我得到“不再引用 cascade="all-delete-orphan" 的集合“ 错误。由于我没有触及任何其他设置/获取父母或孩子的代码,并且只是试图修复 DAO 方法,并且查询只是执行 sql SELECT,所以任何人都可以看到代码被破坏的原因吗?

该问题似乎类似于Spring 事务管理中断休眠级联

4

2 回答 2

0

这不太可能是 Spring 的问题,而是您的实体处理/定义的问题。当您在关系上使用时,不得从实体本身中删除deleteOrphans底层。您只能修改集合实例本身。因此,如果您想在实体设置器中做任何聪明的事情,那就是原因。PersistentSet

此外,据我记得,当您deleteOrphans在关系的双方都有一些问题和/或在一个会话中加载/操作双方时会出现一些问题。


顺便提一句。我认为没有"hibernate.current_session_context_class", "org.hibernate.context.ThreadLocalSessionContext"必要。在我们的项目中,这是我们唯一的配置:

@Bean
public LocalSessionFactoryBuilder sessionFactoryBuilder() {
    return ((LocalSessionFactoryBuilder) new LocalSessionFactoryBuilder(
            dataSourceConfig.dataSource()).scanPackages(ENTITY_PACKAGES).
            setProperty("hibernate.id.new_generator_mappings", "true").
            setProperty("hibernate.dialect", dataSourceConfig.dialect()).
            setProperty("javax.persistence.validation.mode", "none"));
}

@Bean
public SessionFactory sessionFactory() {
    return sessionFactoryBuilder().buildSessionFactory();
}
于 2013-06-15T08:58:00.490 回答
0

问题在于会话管理。正在执行自己的会话处理的其他模块正在调用相同的事务代码块。更糟糕的是,一些调用模块是 Spring bean,而另一些是直接用 Hibernate API 风格编写的。这种混乱足以使我们无法立即升级到 Hibernate 4。

本课的寓意(你喜欢那种英语吗?):在整个项目中使用一致的 DAO 实现,并坚持明确定义的会话和事务管理策略。

于 2013-06-25T22:16:38.397 回答