我正在将一个工作项目从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=的集合”所有-删除-孤立“不再被引用”错误。由于我没有接触任何其他设置/获取父级或子级的代码,而只是尝试修复DAO方法,而查询只是执行sql SELECT,所以有人能看出代码为什么会出错吗?
这个问题似乎与Spring transaction management breaks hibernate cascade类似
发布于 2013-06-15 16:58:00
这不太可能是Spring的问题,而是实体处理/定义的问题。当您在关系上使用deleteOrphans时,不能从实体本身中移除底层的PersistentSet 。您只能修改set实例本身。所以,如果你想在你的实体setter中做任何聪明的事情,那就是原因。
此外,据我所知,当你在关系的两端都有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-26 06:16:38
问题出在会话管理上。正在进行自己的会话处理的其他模块正在调用相同的事务性代码块。雪上加霜的是,一些调用模块是Spring bean,而另一些则是用直接Hibernate API风格编写的。这种杂乱无章的工作足以阻止我们立即升级到Hibernate 4。
教训(你喜欢这个英语吗?):在整个项目中使用一致的DAO实现,并坚持明确定义的会话和事务管理策略。
https://stackoverflow.com/questions/17118688
复制相似问题