0

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

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

  1. 我在会话中从数据库中获取父对象,因此该父对象将在会话中。
  2. 我创建了一个新的子记录并将这个子记录关联到父表,因为父是会话的一部分休眠必须注意在子表中添加子记录正确??
  3. 然后我将在这一点上执行刷新。
  4. 我再次将一个新的孩子添加到父母的集合中
  5. 正如之前所说的hibernate必须注意添加它的仪式?
  6. 我现在再次执行冲洗。
  7. 在 EJB 事务结束时,休眠将生成所有其他 sql 语句。

执行这些操作后,我看到在数据库中只有第二次添加的子项与父表相关联。但是对于第一个子项存在但父关联未设置。

如果我在添加孩子之间删除冲洗,两个孩子都与父母正确关联。冲洗在这里造成问题,但我必须不惜一切代价在这里使用冲洗,因为考虑到我在一次拍摄时关联了 100 个孩子执行刷新,稍后我将关联另外 10 个孩子,然后进行刷新,只有最后 10 个孩子与父母相关联,所有其他孩子都处于孤儿阶段。这对我来说是个问题!:(

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

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

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

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

4

1 回答 1

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 工作双向链接

于 2013-09-24T14:01:03.813 回答