我在 Hibernate 中有一个事务。我使用 session.save()
保存对象,使用 session.getNamedQuery().executeUpdate()
保存其他对象。
问题是第二个对象依赖于第一个对象的存在,但即使两个调用都在同一个事务上,当我尝试使用 namedQuery 插入时,第一个对象“仍然不存在”。
如果我 flush()
session 它会工作,但如果像这样操作 session 是个好习惯,我现在不会。
Session session = HibernateSessionManager.getSessionFactory().getCurrentSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
session.save(myObjectToSave);
session.flush(); //only works with this line in between
session.getNamedQuery("ar.com.portal.bean.Application.insertLang").executeUpdate();
transaction.commit();
} catch (Exception e) {
if (transaction != null) transaction.rollback();
throw e;
}
这是正确的解决方案吗?或者这取决于一些配置参数?我是 Hibernate 的新手。
编辑:
这些是我在 hibernate.cfg.xml 中的属性
<property name="connection.pool_size">10</property>
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
namedQuery 的内容
<sql-query name="insertLang" >
insert into APPLICATION_LANG (APPLICATION_ID, ISO_LANGUAGE_ID, WORKSPACE_ID, NAME, DESCRIPTION)
values ( :id, :lang, :systemObject.workspace.id, :name, :description)
</sql-query >
最佳答案
Hibernate 在执行 native SQL 查询之前不会刷新任何内容。请注意,HQL 不是这种情况,因为 Hibernate 知道查询中使用了哪些实体,因此它可以在查询执行之前自动执行必要的刷新。看这个blog了解更多详情。
因此,您可以按照您已经完成的方式解决问题(在查询之前显式刷新所有内容),或者您可以定义同步实体类:
((SQLQuery) session.getNamedQuery("..."))
.addSynchronizedEntityClass(MyObjectToSaveClass.class)
.executeUpdate();
后一种方法更好,因为如果没有与 MyObjectToSaveClass
实体相关的未决(未刷新)DML 更改,它不会执行任何刷新,并且因为它不会使整个二级缓存无效(请参阅此answer 了解更多详情)。
关于java - Hibernate - 在同一事务中使用 getNamedQuery 保存和插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34965226/