如何将实体与空列表合并?

时间:2016-06-01 08:21:09

标签: java spring hibernate

我的@Entity Set默认为null。 最初创建实体或在@Transactional方法中获取实体时更新实体,一切正常。

但是:当我尝试合并一个分离的实体时,我得到一个HibernateException,即使我根本没碰到孩子Set

@Entity
public class MyEntity {
   @OneToMany(mappedBy = "myEntity", cascade = CascadeType.ALL, orphanRemoval = true)
   @OnDelete(action = OnDeleteAction.CASCADE)
   private Set<ChildEntity> child = null; //by default

   public Set<ChildEntity> getChild() {
       if (child == null) {
           child = new LinkedHashSet<>();
       }
       return child;
   }
}

我可以保存实体而无需初始化子列表:

@Transactional
public MyEntity create() {
    MyEntity entity = new MyEntity();
    //set some params (but not the child object)
    dao.save(entity);
    return entity; //OK though child=null
}

但是以下合并失败了:

MyEntity entity = service.create(); //see above
rsp = runLongTask();
updateSomeParams(entity, rsp); //not touching child
dao.merge(entity); //throws HibernateException

结果:

Caused by: org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: MyEntity.child
    at org.hibernate.engine.internal.Collections.processDereferencedCollection(Collections.java:114) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.engine.internal.Collections.processUnreachableCollection(Collections.java:67) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushCollections(AbstractFlushingEventListener.java:258) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:103) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:55) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1258) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517) ~[spring-orm-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    ... 33 more

为什么我不能将实体与null列表合并?如何防止异常?

1 个答案:

答案 0 :(得分:0)

因为你创建一个新的子(child = new LinkedHashSet&lt;&gt;();)每次child为null你可以在create方法中尝试以下

@Transactional
public MyEntity create() {
    MyEntity entity = new MyEntity();
    //set some params (but not the child object)
    entity.getChild().clear(); //Remove all of the elements from this set 
    dao.save(entity);
    return entity; //OK though child=null
}

基本上,如果你不打算设置它,请删除集合中的所有元素