Mixing Joined and Table per concrete class inheritance
I have classes A, B, C, D, E and F where B extends from A, C extends from B D extends from A, E extends from D F extends from A.
I want to use Joined inheritance strategy at A and Table per concrete class inheritance strategy from B,D and F level. A,B and D are abstract classes and C,E and F are concrete classes.
Is this possible and if yes how should we do it. When I try, I end up getting separate tables for all 6 classes and I want 4 tables to get created (one for A and 3 for C,E and F respectively).
I used @Inheritance(strategy = InheritanceType.JOINED) in class A and @Inh开发者_开发技巧eritance(strategy = InheritanceType.TABLE_PER_CLASS) in classes B,D and F
I have seen examples to mix table per hierarchy and joined inheritance strategies but I want to implement what I mentioned above without using table per hierarchy.
Please help me out.
"Table per concrete class" and "joined subclasses" strategies cannot be mixed because they're mutually exclusive:
- "Table per concrete class" means ALL properties of the class - including inherited - should be mapped to a table associated with a concrete class.
- "Joined subclasses" means ONLY properties of this specific class - excluding inherited - should be mapped to a table associated with this class.
With that in mind, taking your example of classes A, B and C and you wanting to mix the above strategies at B level, what should Hibernate do with C?
- C is using "table per concrete class" and so should have all properties of A, B, C mapped to "C_table".
- A is using "joined subclasses" and so should have all of its own properties mapped to "A_table".
You've now got your data duplicated in 2 tables. Repeat that with E and F and it's 4 tables.
This is a bit late, but I had a similar problem recently. The solution that I found is to use @MappedSuperclass annotation on the abstract classes for which you don't want separate tables.
For example,
@Entity(name = "A")
@Inheritance(strategy = InheritanceType.JOINED)
public class A {
// mapped fields that go into parent A table
}
@MappedSuperclass
public class B extends A {
// fields that should get pushed down to tables that inherit from B
}
@MappedSuperclass
public class D extends A {
// fields that should get pushed down to tables that inherit from D
}
@Entity(name = "F"
public class F extends A {
// fields that are specific to table F
}
@Entity(name = "C")
public class C extends B {
// fields that are specific to table C
}
@Entity(name = "E")
public class E extends D {
// fields that are specific to table E
}
This assumes that the mappings that you apply in the @MappedSuperclass
classes (in particular, the column names) are the same for the subclass tables. If they aren't, you need to use the @AttributeOverride
annotation on the class. For example,
@MappedSuperclass // this insures that no table is created for this class, but that the mapped fields are pushed down to the subclasses.
public class B extends A {
@Id @Generated
@Column(name = "myId")
public int myId;
}
@Entity(name = "C")
@AttributeOverride(name = "myId", column = @Column(name = "ID"))
public class C extends B {
}
精彩评论