Search code examples
javajpamany-to-manyeclipselink

Why is persist method called twice?


In my service level I create a new object from Entity1 class and persist it and then call setters on it. but after all, another object from Entity1 will be created and inserted in database( so I will have two rows in Entity1 table inserted in database instead of one). MyEntity1 has a many-to-many relationship with itself and I set it after calling persist method. My problem is that I can't find why an additional Entity1 object is created in my application.

My service class:

MyEntity1 e1 = new MyEntity1();
em.persist(e1); 
MyEntity2 e2 = new MyEntity2();
e2.setChild(e1);
e2.setParent(e1);
e1.getParent().add(e2);
e1.getChildren().add(e2);

MyEntity1 class has two oneToMany relationships with itself (it is a manyToMany relation with additional column):

MyEntity1 class:

 @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "child", orphanRemoval = true)
    private List<MyEntity2> parent = new ArrayList<MyEntity2>();

 @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "parent")  
    private List<MyEntity2> children= new ArrayList<MyEntity2>();

Solution

  • If I understood you correctly (which is hard without some code), you persist an entity and after that add a relationship to another instance?

    When you call persist on an entity, it becomes managed entity which means JPA provider now manages its lifecycle. That means you no longer have to call merge or persist on it in order to save changes. JPA provider does this automatically, and that's why the second entity is also persisted.

    MyEntity e1 = new MyEntity();
    em.persist(e1); // this persists the entity, and makes it managed 
    MyEntity e2 = new MyEntity();
    e1.setRelation(e2);
    // this will also persist (if cascade is properly configured) e2 at the end of transaction, without you persisting it manually