我正在尝试从双向关联中删除子元素。我要强调的是,如果我查询Employee实例,然后使用getChildren()方法获取关联的子代,那么父记录和子记录都将被管理。现在,当我调用child.setParent(null)和parent.getChildren().remove(child)时,这两个更新都应该在事务提交时持久化,但是我得到了:org.hibernate.AssertionFailure: collection [org.rand.model.Employee.children] was not processed by flush()异常,除非我对子元素调用merge或通过查询获取子元素。
有人能解释一下为什么会这样吗?
我使用的是hibernate 3.5.6-最终版
谢谢
更新:经过一段时间的调试,我找到了导致这个错误的代码,我一定是在发帖的时候不小心把它删除了。我对此表示诚挚的道歉。
罪魁祸首是自定义OneToManyInverseCheck bean验证器,该验证器正在验证父进程和子进程上是否都设置了关系。这在提交操作期间触发了附加实体(子项的子项)的加载。
实体:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.TABLE)
private int id;
@Version
private int version;
private String name;
@ManyToOne
private Employee parent;
@OneToMany(mappedBy="parent")
@OneToManyInverseCheck(inverseFieldName="parent")
private List<Employee> children;
//get/set methods ommitted
}简单JUnit:
public class JPAUpdate {
private static EntityManagerFactory emf;
private EntityManager em;
@BeforeClass
public static void init() {
emf = Persistence.createEntityManagerFactory("myapp-db");
}
@Before
public void setUp() throws Exception {
em = emf.createEntityManager();
}
@Test
public void removeChildWithMerge() {
em.getTransaction().begin();
Employee e = em.createQuery("from Employee e where e.children is not empty order by e.id asc", Employee.class).getResultList().get(0);
Employee child = e.getChildren().get(0);
child.setParent(null);
e.getChildren().remove(child);
// removing this merge causes org.hibernate.AssertionFailure: collection [org.rand.model.Employee.children] was not processed by flush()
em.merge(child);
em.getTransaction().commit();
}
@Test
public void removeChildWithFetch() {
em.getTransaction().begin();
Employee e = em.createQuery("from Employee e left join fetch e.children where e.children is not empty order by e.id asc", Employee.class).getResultList().get(0);
Employee child = e.getChildren().get(0);
child.setParent(null);
e.getChildren().remove(child);
//em.merge(child); - no merge needed
em.getTransaction().commit();
}
@Test
public void removeChild() {
em.getTransaction().begin();
Employee e = em.createQuery("from Employee e left join fetch e.children where e.children is not empty order by e.id asc", Employee.class).getResultList().get(0);
Employee child = e.getChildren().get(0);
child.setParent(null);
e.getChildren().remove(child);
//em.merge(child); - no merge needed
em.getTransaction().commit();
}
}发布于 2014-07-15 18:31:04
这可能是因为在removeChildWithMerge中,您的子集合是延迟加载的,并且在刷新期间触发了项的加载,从而导致了此异常。您可以使用Hibernate.inititalize(obj)而不是调用merge。另一方面,在removeChildWithFetch中,您正在使用fetch来急切地加载集合,因此在刷新期间集合items.So已经加载,所以没有问题。
发布于 2020-02-13 01:08:45
对于我的案例,我用以下方式解决了它:
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager entityManager;https://stackoverflow.com/questions/24755073
复制相似问题