How to persist a Hibernate child entity without loading the parent-side Set collection

后端 未结 2 1007
暗喜
暗喜 2021-01-07 09:51

We are using Hibernate 3.5.6-Final with Hazelcast 3.6.1 2nd level cache.

Situation

I have a bi-directional, one-to-many relation between a Parent

相关标签:
2条回答
  • 2021-01-07 10:36

    I found a solution to my problem. I solved it by adding a new method addChild to the Parent that looks as follows:

     public void addChild(Child child) {
         child.setParent(this);
         if (Hibernate.isInitialized(getChildren()) {
             getChildren().add(child);
         } else {
             Hibernate.getSessionFactory().getCache().evictCollection(
                 getClass().getName()+".children", this.getId());
         }
     }
    

    Thus: if the children have already been loaded for some reason, the new child is added to the children set. This ensures that an already loaded set stays consistent. If the set is not loaded yet, I just set the parent to the child and evict the 2nd level cache (that this is needed is described here: https://github.com/hibernate/hibernate-orm/pull/580). As the set is not loaded yet it can also not be inconsistent. When the set is accessed afterwards, Hibernate will load the set including the new child.

    0 讨论(0)
  • 2021-01-07 10:43

    There's a better way:

    1. You need to make the many-to-one side lazy.

      <many-to-one name="parent"
          class="Parent"
          cascade="none"
          column="parent_id"
          not-null="true"
          lazy="true"/>
      
    2. As long as you don't need to fetch the Parent entity in the currently running Persistence Context, you can just fetch a Proxy reference:

      Parent parentProxy = session.load(Parent.class, parentId);
      
    3. Now, you can simply create a new child as follows:

      Child newChild = new Child();
      child.setParent(parentProxy);
      session.persist(newChild);
      

    Another workaround is as follows:

    You don't even fetch a Parent Proxy reference, but instead, you do as follows:

    Parent parentReference = new Parent();
    parentReference.setId(parentId);
    
    Child newChild = new Child();
    child.setParent(parentReference);
    session.persist(newChild);
    

    This way, you don't need to fully fetch the Parent entity if all you need is to persist a Child entity.

    0 讨论(0)
提交回复
热议问题