添加@Transactional导致“cascade =”all-delete-orphan“的集合不再被引用”

时间:2013-06-14 23:27:50

标签: spring hibernate

我正在将一个工作项目从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注释似乎已经在我在stacktrace

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

在初始化期间,上面列出的更改似乎适用于对loadTable函数的一些调用,但是当它转向加载具有父项的实体时,我得到了带有cascade =&#34;的所有&#34;集合-delete-孤儿&#34;不再被引用&#34;错误。由于我没有触及设置/获取父项或子项的任何其他代码,并且我只是尝试修复DAO方法,并且查询只执行sql SELECT,有人可以看到代码被破坏的原因吗?

问题与Spring transaction management breaks hibernate cascade

类似

2 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分:0)

问题在于会话管理。正在进行自己的会话处理的其他模块正在调用相同的事务代码块。为了增加我们的困境,一些调用模块是Spring bean,而其他模块是用直接的Hibernate API风格编写的。这种混乱是让我们立即远离Hibernate 4的充分工作。

课程的道德(你喜欢英语怎么样?):在整个项目中使用一致的DAO实施,并坚持明确定义的会话和交易管理策略。