Java 解析Transaction中的一对多关系会返回不完整的集合

Java 解析Transaction中的一对多关系会返回不完整的集合,java,hibernate,jpa,jta,Java,Hibernate,Jpa,Jta,在复杂的UserTransaction(ut)中,我们必须找到一个JPA实体,添加一个新的子实体,然后再次找到父实体。我们观察到,当我们在事务中获取父级时,子级列表是不完整的,并且在事务提交后按预期完成。所有内容都是单线程的,并使用相同的实体管理器实例 我们是否遗漏了一些可以解释这种行为的显而易见的东西 ut.begin(); // find the parent entity ParentEntity parent = em.find(parentKey); assertEquals(par

在复杂的UserTransaction(ut)中,我们必须找到一个JPA实体,添加一个新的子实体,然后再次找到父实体。我们观察到,当我们在事务中获取父级时,子级列表是不完整的,并且在事务提交后按预期完成。所有内容都是单线程的,并使用相同的实体管理器实例

我们是否遗漏了一些可以解释这种行为的显而易见的东西

ut.begin();

// find the parent entity
ParentEntity parent = em.find(parentKey);
assertEquals(parent.getChildren().size(), 1);   // as expected

// add one child
ChildEntity child = createChild();        // create child for the parent
child.setParentRef(parent.getRef());
em.persist(child);
em.flush();

// find the parent entity again
ParentEntity parent = em.find(parentKey);
assertEquals(parent.getChildren().size(), 1);   // UNEXPECTED! Should be two...

ut.commit();

// find the parent entity again
ParentEntity parent = em.find(parentKey);

assertEquals(parent.getChildren().size(), 2);   // now I see 2 children. After committing
父级上的关系定义如下:

@OneToMany(orphanRemoval=true, cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JoinColumn(name="parent_ref", referencedColumnName="ref")
List<ChildEntity> children = new ArrayList<ChildEntity>();
@OneToMany(orphanRemoving=true,cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinColumn(name=“parent\u ref”,referencedColumnName=“ref”)
List children=new ArrayList();

您需要向父集合添加新的子集合:

ChildEntity child = createChild();
child.setParentRef(parent.getRef());
parent.getChildren().add(child);
em.persist(parent);
em.persist(child); // only required if the persist does not cascade to children
em.flush();

您需要向父集合添加新的子集合:

ChildEntity child = createChild();
child.setParentRef(parent.getRef());
parent.getChildren().add(child);
em.persist(parent);
em.persist(child); // only required if the persist does not cascade to children
em.flush();

您需要向父集合添加新的子集合:

ChildEntity child = createChild();
child.setParentRef(parent.getRef());
parent.getChildren().add(child);
em.persist(parent);
em.persist(child); // only required if the persist does not cascade to children
em.flush();

您需要向父集合添加新的子集合:

ChildEntity child = createChild();
child.setParentRef(parent.getRef());
parent.getChildren().add(child);
em.persist(parent);
em.persist(child); // only required if the persist does not cascade to children
em.flush();

这完全是意料之中的。您设置了子项的父项,但未将子项添加到父项列表中。所有这些都在一个事务中,因此对
em.find(parentKey)
的第二次调用返回的父对象直接来自一级缓存,因此与第一次调用返回的对象完全相同


维护事务中对象图的一致性是您的责任。请参见

这完全是意料之中的事。您设置了子项的父项,但未将子项添加到父项列表中。所有这些都在一个事务中,因此对
em.find(parentKey)
的第二次调用返回的父对象直接来自一级缓存,因此与第一次调用返回的对象完全相同


维护事务中对象图的一致性是您的责任。请参见

这完全是意料之中的事。您设置了子项的父项,但未将子项添加到父项列表中。所有这些都在一个事务中,因此对
em.find(parentKey)
的第二次调用返回的父对象直接来自一级缓存,因此与第一次调用返回的对象完全相同


维护事务中对象图的一致性是您的责任。请参见

这完全是意料之中的事。您设置了子项的父项,但未将子项添加到父项列表中。所有这些都在一个事务中,因此对
em.find(parentKey)
的第二次调用返回的父对象直接来自一级缓存,因此与第一次调用返回的对象完全相同

维护事务中对象图的一致性是您的责任。参见

非常感谢!成功了!(虽然我不坚持,但合并,因为它已经存在:))非常感谢!成功了!(虽然我不坚持,但合并,因为它已经存在:))非常感谢!成功了!(虽然我不坚持,但合并,因为它已经存在:))非常感谢!成功了!(虽然我不持久化父级,但合并它,因为它已经存在:))