Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA Mixed Inheritance Strategy

I have 3 entities:

@Entity
public abstract class A {
  @Id
  public Long id;
  public String a1;
  public String a2;
  public String a3;

  //much more fields    
  //getters and setters
}

@Entity
public class B extends A {
  public String b1;
  public String b2;
  public String b3;

  //much more fields
  //getters and setters
}

@Entity
public class C extends A {
  public String c;
  //that's it. no more data

  //getters and setters
}

I want to map these classes to 2 tables. First one will contain all of A and C data (i.e. SINGLE_TABLE inheritance). And the second one will contain B's data and a foreign key to A (i.e. JOINED inheritance).

I tried the solution proposed here, but it doesn't work for me. The attributes of BB1 and BB2 are also included into A.

How to implement such a strategy? Classes A and C are as different as Dog and Cat are, so I can't merge them into one class.

Also I don't want to use table-per-hierarchy which would result in duplicating lots of A's data.

like image 293
jFrenetic Avatar asked Oct 06 '11 20:10

jFrenetic


2 Answers

JPA spec (paragraph 2.12) is saying that Support for the combination of inheritance strategies within a single entity inheritance hierarchy is not required by this specification. Keeping that in mind, in similar cases I usually use JOINED strategy for all of my entities.

like image 122
andbi Avatar answered Oct 22 '22 11:10

andbi


After spending so much time on this, and not getting any answer, I've come to this solution (which could be not the best):

@Entity
public abstract class A implements Serializable {
  @Id
  public Long id;

  public String a1;
  public String a2;
  public String a3;

  //much more fields    
  //getters and setters
}

@Entity
public class B implements Serializable {

  @Id  
  @Column(name="id", nullable=false)  
  public Long id;

  @MapsId  
  @OneToOne(optional=false)  
  @JoinColumn(name="id")  
  public A a;

  public String b1;  
  public String b2;  
  public String b3;

  //much more fields
  //getters and setters
}

@Entity
public class C extends A {  

  public String c;
  //that's it. no more data

  //getters and setters
}

Conclusion
I was amazed at how such well-supported and popular technology as JPA does not offer a solution for such a trivial case. As pointed out by Pascal Thivent in his answer to this question, Hibernate is cheating us, using a secondary table, which is a very tedious and error-prone approach (you should manually specify for each field, to which table it belongs). So it looks like, there is still a room for improvement in JPA spec.

like image 27
jFrenetic Avatar answered Oct 22 '22 12:10

jFrenetic