Hi, I have a problem trying to map an inheritance tree. A simplified version of my model is like this:
@MappedSuperclass @Embeddable public class BaseEmbedded implements Serializable {
@Column(name="BE_FIELD") private String beField; // Getters and setters follow }
@MappedSuperclass @Embeddable public class DerivedEmbedded extends BaseEmbedded {
@Column(name="DE_FIELD") private String deField; // Getters and setters follow }
@MappedSuperclass public abstract class BaseClass implements Serializable {
@Embedded protected BaseEmbedded embedded;
public BaseClass() { this.embedded = new BaseEmbedded(); }
// Getters and setters follow }
@Entity @Table(name="MYTABLE") @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING) public class DerivedClass extends BaseClass {
@Id @Column(name="ID", nullable=false) private Long id;
@Column(name="TYPE", nullable=false, insertable=false, updatable=false) private String type;
public DerivedClass() { this.embedded = new DerivedClass(); }
// Getters and setters follow }
@Entity @DiscriminatorValue("A") public class DerivedClassA extends DerivedClass {
@Embeddable public static NestedClassA extends DerivedEmbedded { @Column(name="FIELD_CLASS_A") private String fieldClassA; }
public DerivedClassA() { this.embedded = new NestedClassA(); }
// Getters and setters follow }
@Entity @DiscriminatorValue("B") public class DerivedClassB extends DerivedClass {
@Embeddable public static NestedClassB extends DerivedEmbedded { @Column(name="FIELD_CLASS_B") private String fieldClassB; }
public DerivedClassB() { this.embedded = new NestedClassB(); }
// Getters and setters follow }
At Java level, this model is working fine, and I believe is the appropriate one. My problem comes up when it's time to persist an object.
At runtime, I can create an object which could be an instance of DerivedClass, DerivedClassA or DerivedClassB. As you can see, each one of the derived classes introduces a new field which only makes sense for that specific derived class. All the classes share the same physical table in the database. If I persist an object of type DerivedClass, I expect fields BE_FIELD, DE_FIELD, ID and TYPE to be persisted with their values and the remaining fields to be null. If I persist an object of type DerivedClass A, I expect those same fields plus the FIELD_CLASS_A field to be persisted with their values and field FIELD_CLASS_B to be null. Something equivalent for an object of type DerivedClassB.
Since the @Embedded annotation is at the BaseClass only, Hibernate is only persisting the fields up to that level in the tree. I don't know how to tell Hibernate that I want to persist up to the appropriate level in the tree, depending on the actual type of the embedded property.
I cannot have another @Embedded property in the subclasses since this would duplicate data that is already present in the superclass and would also break the Java model.
I cannot declare the embedded property to be of a more specific type either, since it's only at runtime when the actual object is created and I don't have a single branch in the hierarchy.
Is it possible to solve my problem? Or should I resignate myself to accept that there is no way to persist the Java model as it is?
Any help will be greatly appreciated. Thanks
|