首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >flush()未处理集合

flush()未处理集合
EN

Stack Overflow用户
提问于 2014-07-15 17:53:25
回答 2查看 6.3K关注 0票数 2

我正在尝试从双向关联中删除子元素。我要强调的是,如果我查询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验证器,该验证器正在验证父进程和子进程上是否都设置了关系。这在提交操作期间触发了附加实体(子项的子项)的加载。

实体:

代码语言:javascript
复制
@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:

代码语言:javascript
复制
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();
    }
}
EN

回答 2

Stack Overflow用户

发布于 2014-07-15 18:31:04

这可能是因为在removeChildWithMerge中,您的子集合是延迟加载的,并且在刷新期间触发了项的加载,从而导致了此异常。您可以使用Hibernate.inititalize(obj)而不是调用merge。另一方面,在removeChildWithFetch中,您正在使用fetch来急切地加载集合,因此在刷新期间集合items.So已经加载,所以没有问题。

票数 4
EN

Stack Overflow用户

发布于 2020-02-13 01:08:45

对于我的案例,我用以下方式解决了它:

代码语言:javascript
复制
@PersistenceContext(type = PersistenceContextType.EXTENDED)
  private EntityManager entityManager;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24755073

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档