Assuming we have the following entities:
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL)
private List<Phone> phones = new ArrayList<>( );
public Person() {}
public Person(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public List<Phone> getPhones() {
return phones;
}
public void addPhone(Phone phone) {
phones.add( phone );
phone.setPerson( this );
}
}
@Entity
public class Phone {
@Id
@GeneratedValue
private Long id;
@ManyToOne
private Person person;
private String number;
public Phone() {
}
public Phone(String number) {
this.number = number;
}
public Long getId() {
return id;
}
public String getNumber() {
return number;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
When running the following test case:
final Person vlad = doInJPA( this::entityManagerFactory, entityManager -> {
Person person = new Person( "Vlad" );
entityManager.persist( person );
return person;
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Phone phone = new Phone( "1234567890" );
vlad.addPhone( phone );
entityManager.persist( phone );
Person person = entityManager.createQuery( "select p from Person p", Person.class).getSingleResult();
assertEquals(1, person.getPhones().size());
} );
The EntityManager is notified to persist the new phone entity, which is queued and waits for a flush to be inserted into the database. Meanwhile, we retrieve its parent entity (which hasn't been loaded before in the current persistence context - we were just using a detached object for setting the person @ManyToOne relationship). When getting the child entity collection, Hibernate doesn't trigger a flush since it considers there's no overlapping between the person child entity and the person parent one. This leads to an inconsistency because the child entity collection is empty and the test fails. If the flush were triggered, the parent entity should have seen the newly persisted child entity. Test case will be added after knowing the issue number. |