【问题标题】:Hibernate - save and inserting with getNamedQuery in same transactionHibernate - 在同一事务中使用 getNamedQuery 保存和插入
【发布时间】:2016-04-30 03:31:00
【问题描述】:

我在 Hibernate 中有一个事务。我保存了一个对象使用session.save() 和其他使用session.getNamedQuery().executeUpdate()。 问题是第二个对象取决于第一个对象的存在,但即使两个调用都在同一个事务上,当我尝试使用 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 >

【问题讨论】:

  • 配置的flush模式是什么?
  • 在我的 hibernate.cfg 中添加了属性。与flush无关,所以我认为它是默认值。
  • 您正在执行的命名查询中有什么?
  • 这是另一个表上的插入(但相关)。添加代码。
  • 好的,这是一个原生查询,因此没有自动刷新。请在下面查看我的答案。

标签: java hibernate session


【解决方案1】:

Hibernate 在执行本机 SQL 查询之前不会刷新任何内容。请注意,HQL 不是这种情况,因为 Hibernate 知道查询中使用了哪些实体,因此它可以在查询执行之前自动执行必要的刷新。有关详细信息,请参阅此blog

因此,您可以按照已经解决的方式解决问题(在查询之前显式刷新所有内容),或者您可以定义同步实体类:

((SQLQuery) session.getNamedQuery("..."))
  .addSynchronizedEntityClass(MyObjectToSaveClass.class)
  .executeUpdate();

后一种方法更好,因为如果没有与MyObjectToSaveClass 实体相关的未决(未刷新)DML 更改,它不会执行任何刷新,并且不会使整个二级缓存无效(有关更多信息,请参阅answer详情)。

【讨论】:

  • 测试第二个选项。效果很好,很有意义!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多