Here the scenario: I have a unidirectional 1:N Relation from Person Entity to Address Entity. And a bidirectional 1:N Relation from User Entity to Vehicle Entity.
Here is the Address class:
@Entity
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
privat Long int
...
The Vehicles Class:
@Entity
public class Vehicle implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
private User owner;
...
@PreRemove
protected void preRemove() { //this.owner.removeVehicle(this); }
public Vehicle(User owner) {
this.owner = owner;
...
The Person Class:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name="PERSON_TYP")
public class Person implements Serializable {
@Id
protected String username;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval=true)
@JoinTable(name = "USER_ADDRESS",
joinColumns =
@JoinColumn(name = "USERNAME"),
inverseJoinColumns =
@JoinColumn(name = "ADDRESS_ID"))
protected List<Address> addresses;
...
@PreRemove
protected void prePersonRemove(){ this.addresses = null; }
...
The User Class which is inherited from the Person class:
@Entity
@Table(name = "Users")
@DiscriminatorValue("USER")
public class User extends Person {
@OneToMany(mappedBy = "owner", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<Vehicle> vehicles;
...
When I try to delete a User who has an address I have to use orphanremoval=true on the corresponding relation (see above) and the preRemove function where the address List is set to null. Otherwise (no orphanremoval and adress list not set to null) a foreign key contraint fails. When i try to delete a user who has an vehicle a concurrent Acces Exception is thrown when do not uncomment the "this.owner.removeVehicle(this);" in the preRemove Function of the vehicle.
The thing i do not understand is that before i used this inheritance there was only a User class which had all relations:
@Entity
@Table(name = "Users")
public class User implements Serializable {
@Id
protected String username;
@OneToMany(mappedBy = "owner", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<Vehicle> vehicles;
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "USER_ADDRESS",
joinColumns =
@JoinColumn(name = "USERNAME")
inverseJoinColumns =
@JoinColumn(name = "ADDRESS_ID"))
ptivate List<Address> addresses;
...
No orphanremoval, and the vehicle class has used the uncommented statement above in its preRemove function. And - I could delte a user who has an address and i could delte a user who has a vehicle. So why doesn't everything work without changes when i use inheritance?
To perform the deletion creation and so on i use session facades:
helper // used to get a reference to the Session Beans
tx.begin(); // start UserTransaction
helper .getUserFacade().create(user); // where em.persist(user); is called
tx.commit();
... // add an address or remove an adress...
tx.begin();
helper.getUserFacade().edit(user); // where em.merge(user); is called
tx.commit();
tx.begin();
helper.getUserFacade().remove(user); // where em.remove(em.merge(user)); is called
tx.commit();
I use JPA 2.0, EclipseLink 2.0.2, MySQL 5.1.x and Netbeans 6.8