Here is a simplified version of the test. For getting higher priority - please submit tests in this format:
import java.util.*;
import javax.persistence.*;
public class T606 {
public static void main(String[] args) {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory(
"objectdb://localhost:6136/test/test.tmp;drop;admin");
EntityManager em = emf.createEntityManager();
Contact contact = new Contact("TEST");
contact.getAddresses().add(new Address("1", "1", "1"));
contact.getAddresses().add(new Address("2", "2", "2"));
em.getTransaction().begin();
em.persist(contact);
em.getTransaction().commit();
printCounts(em);
em.close();
em = emf.createEntityManager();
contact = (Contact) em.createQuery("SELECT FROM Contact")
.setMaxResults(1).getSingleResult();
em.getTransaction().begin();
Address address_1 = contact.getAddresses().get(0);
// Remove and add address again -> will be gone
contact.getAddresses().remove(address_1);
contact.getAddresses().add(address_1);
em.getTransaction().commit();
printCounts(em);
em.close();
emf.close();
}
private static void printCounts(EntityManager em) {
int Address_1_Count = ((Long) em.createQuery(
"SELECT COUNT(a) FROM Address a WHERE street = '1'")
.getSingleResult()).intValue();
int Address_2_Count = ((Long) em.createQuery(
"SELECT COUNT(a) FROM Address a WHERE street = '2'")
.getSingleResult()).intValue();
System.out.println("Address_1 Count: " +
Integer.toString(Address_1_Count));
System.out.println("Address_2 Count: " +
Integer.toString(Address_2_Count));
}
@Entity
public static class Contact {
private String name = null;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private List<Address> addresses = null;
public Contact(String name) {
this.name = name;
}
public Contact() {
}
public List<Address> getAddresses() {
if (addresses == null)
addresses = new ArrayList<Address>();
return addresses;
}
}
@Entity
public static class Address {
private String street = null;
private String no = null;
private String city = null;
public Address(String street, String no, String city) {
this.street = street;
this.no = no;
this.city = city;
}
public Address() {
}
}
}
As you indicated, the behavior when using enhancement and using reflection is different. This is the result of different implementation of the action in these two modes.
However, this is not a bug, since according to JPA: "Portable applications must otherwise not depend upon a specific order of removal, and must not reassign an entity that has been orphaned to another relationship or otherwise attempt to persist it", so in your application you should avoid adding the address again after removal.