同一EJB事务中的多次刷新导致第一次刷新的更改消失

时间:2013-09-24 11:29:38

标签: java hibernate ejb sql-update flush

我有一个容器管理的事务,并且在一个方法中有一个与该事务关联的实体管理器。我拥有的表是父表和另一个包含父表子项的表的关联。

在同一会话中,我按以下顺序执行以下项目: 最初在会话中,我们将不会有父对象或子对象。但是父对象将存在于DB中,并且子对象将被添加到我们感兴趣的方法中。

  1. 我从会话中的DB获取父对象,所以这个父对象 对象将在会话中。
  2. 我创建了一个新的子记录,并将这个子关联到父表,因为父对象是hibernate的一部分,必须注意在子表中正确添加子记录吗?
  3. 然后我会在此时进行同花。
  4. 我将再次将新子项添加到父
  5. 的集合中
  6. 如前所述,hibernate必须注意添加它吗?
  7. 我现在再次表演同花顺。
  8. 在EJB事务结束时,hibernate将生成所有其他sql语句。
  9. 执行这些操作后,我看到在DB中只有第二次添加的子项与父表关联。但是第一个子条目存在,但父关联没有设置。

    如果我在添加孩子之间移除了同花顺,两个孩子都正确地与父母联系.Flush在这里引起了一个问题,但我必须不惜任何代价在这里使用同花顺,因为考虑到我正在关联100个孩子一旦射击然后执行同花,然后我将关联另外10个孩子,然后做冲洗只有最后10个孩子与父母相关,所有其他孩子都处于孤儿阶段。这对我来说是一个问题!:(

    请评论如何解决此问题。我应该在刷新之前执行一些其他操作,例如update或saveOrUpdate吗?

    算法在这里请找到它: 由于代码很大很长,我将发布执行操作的算法 假设我有2个表,一个用于名为PARENT的父级,另一个用于名为CHILD的子级 并且子实体从父实体扩展 假设最初我在DB中只有一条父记录,并且子表中没有CHILD记录 孩子与父母一对多和反对之间存在双向联系。 在事务开始时,我将从DB获取父数据,以便父级与持久性上下文相关联。 现在假设我正在为孩子创建一个新的POGO对象并填充其数据。假设我将创建20个这样的对象,然后将子节点双向关联到父节点,将父节点关联到子节点。 由于父级处于hibernate上下文,当我将它与子级hibernate关联时,将负责创建和创建链接。 现在假设我在会话上下文中执行刷新。 接下来,我创建了10个孩子的POGO对象并与父母进行相同的关联,并再次执行刷新。

    在交易结束后,当我检查数据库时,我看到数据库中有前20个条目但是它们与父项的关联不存在。但是对于最后添加的10个Child对象,父项的条目和关联都在那里。

    当我在20到10之间添加孩子之间移除同花时,我看到所有30个都正确关联。我想知道为什么冲洗会导致问题。

1 个答案:

答案 0 :(得分:0)

如果您使用hibernate参考中描述的双向关系,则需要特别小心:

<class name="Person">
 <id name="id" column="personId">
     <generator class="native"/>
 </id>
 <many-to-one name="address"          column="addressId"         not-null="true"/>
</class> 
<class name="Address">
 <id name="id" column="addressId">
     <generator class="native"/>
 </id>
 <set name="people" inverse="true">
     <key column="addressId"/>
     <one-to-many class="Person"/>
 </set>
</class>

在这种情况下,如果你将一个人添加到address.people,但是person.address为null,则hibernate将不会保存该人,因为address.people关系是inverse =“true”。

您需要设置休眠关系的两个方向以正确保存它:

public void addPerson(Person person) {
    person.setAddress(this);
    this.people.add(person);
}

请参阅hibernate教程中的1.2.6 Working bi-directional links