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?