0

I invoke function merge() for root element in the graph of entities. The entities are cascaded. In the graph there are persistent and transient elements. I got insertion one empty extra entity. Entities:

@Entity
public class CnTermsAmortization {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO) 
    Long id;

    @ManyToOne
    private CnTermsCounted cnTermsCounted;

    @ManyToOne
    private CnTermsBudget cnTermsBudget;

    ...

}

@Entity
public class CnTermsBudget {

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;

    @OneToMany(mappedBy = "cnTermsBudget")
    Set<CnTermsAmortization> amortizations = new HashSet<>();

    @ManyToOne
    private CnTermsGroup cnTermsGroup;  

    .....   

}

@Entity
public class CnTermsCounted {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO) 
    Long id;

    @OneToMany(mappedBy = "cnTermsCounted", cascade=CascadeType.ALL, orphanRemoval=true)
    private Set<CnTermsAmortization> amortizations = new HashSet<>();

    @ManyToOne
    private CnTermsGroup cnTermsGroup;
    .....
}

@Entity
public class CnTermsGroup {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO) 
    Long id;        

    @OneToMany(mappedBy="cnTermsGroup", cascade=CascadeType.ALL, orphanRemoval=true)
    private List<CnTermsCounted> cnTermsCounteds = new ArrayList<>();

    @OneToMany(mappedBy="cnTermsGroup", cascade=CascadeType.ALL, orphanRemoval=true)
    private List<CnTermsBudget> cnTermsBudgets = new ArrayList<>();

    .....
}

Controller:

public static void main(String[] args) {
    // Insert data to database
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa");       
    EntityManager em1 = emf.createEntityManager();          
    CnTermsBudget budget = new CnTermsBudget();
    CnTermsCounted counted = new CnTermsCounted();

    CnTermsGroup group = new CnTermsGroup();
    group.getCnTermsBudgets().add(budget);
    group.getCnTermsCounteds().add(counted);

    budget.setCnTermsGroup(group);
    counted.setCnTermsGroup(group);

    EntityTransaction t1 = em1.getTransaction();
    t1.begin();

    Long id = em1.merge(group).getId();

    t1.commit();
    em1.close();

    //Create transient entity 
    CnTermsAmortization amortization = new CnTermsAmortization();           

    EntityManager em = emf.createEntityManager();

    EntityTransaction t = em.getTransaction();
    t.begin();

    //Read persistent graph 
    group = em.find(CnTermsGroup.class, id); 

    budget = group.getCnTermsBudgets().get(0);  
    counted = group.getCnTermsCounteds().get(0);

    //Add transient entity to persistent tree
    budget.getAmortizations().add(amortization);
    counted.getAmortizations().add(amortization);

    amortization.setCnTermsBudget(budget);
    amortization.setCnTermsCounted(counted);

    //merge on the root
    em.merge(group);

    t.commit();

    em.close(); 



    em = emf.createEntityManager();

    List<?> ls = em.createQuery("from CnTermsAmortization").getResultList();
    System.out.println(Arrays.toString(ls.toArray()));

    em.close();
    emf.close();
}

In Hibernate logs I see that two entities are inserted:

Hibernate: insert into CnTermsAmortization (cnTermsBudget_id, cnTermsCounted_id, id) values (?, ?, ?) Hibernate: insert into CnTermsAmortization (cnTermsBudget_id, cnTermsCounted_id, id) values (?, ?, ?)

In controller output I see that one of them have null in all fields:

[CnTermsAmortization [id=1, cnTermsCounted=entities.CnTermsCounted@47747fb9, cnTermsBudget=entities.CnTermsBudget@51684e4a], CnTermsAmortization [id=2, cnTermsCounted=null, cnTermsBudget=null]]

When I invoke merge() on the root of graph where all entities are Transient all works properly - in output I have one entity with filled values. I use Hibernate version 5.1.1, JPA interface. Did I miss something?

1 Answers1

0

This is bug. It have been fixed. Information about bugfix relises here: https://hibernate.atlassian.net/browse/HHH-9512