views:

227

answers:

0

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