我在Hibernate中进行了一次交易。我使用session.save()
保存对象session.getNamedQuery().executeUpdate()
和其他对象。
问题是第二个对象依赖于first的存在,但即使两个调用都在同一个事务上,第一个对象仍然不存在"当我尝试使用namedQuery插入时。
如果我flush()
它的会话有效,但我现在不是这样操作会话的好习惯。
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 >
答案 0 :(得分:1)
在执行本机SQL查询之前,Hibernate不会刷新任何内容。请注意,HQL不是这种情况,因为Hibernate知道查询中使用了哪些实体,因此它可以在查询执行之前自动执行必要的刷新。有关详细信息,请参阅此blog。
因此,您可以按照已经完成的方式解决问题(在查询之前显式刷新所有内容),或者您可以定义同步的实体类:
((SQLQuery) session.getNamedQuery("..."))
.addSynchronizedEntityClass(MyObjectToSaveClass.class)
.executeUpdate();
后一种方法更好,因为如果没有与MyObjectToSaveClass
实体相关的待处理(未刷新)DML更改,并且它不会使整个二级缓存无效,它将不会执行任何刷新(请参阅此{{3更多细节)。