I have an object with a field that can be a number of object types. This object is encoded in a single table with a discriminator column for the field's subtypes. Each of these subtypes have their fields mapped to a column in the parent objects table. I cannot seem to model this in hibernate. The code bellow will return null for getSubfield()
regardless of what subtype data is in the table.
Schema
id type whosit whatsit +----+------+--------+---------+ | 1 | "A" | "test" | null | | 2 | "B" | null | "test" | +----+------+--------+---------+
Domain Objects
@Entity
public class Parent {
protected @Id @GeneratedValue int id;
protected Subfield subfield;
public Subfield getSubfield() {return subfield;}
}
@Embeddable
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type", discriminatorType=DiscriminatorType.STRING)
public abstract class Subfield {}
@DiscriminatorValue("A")
public class TypeA extends Subfield {
public String whosit;
}
@DiscriminatorValue("B")
public class TypeB extends Subfield {
public String whatsit;
}
"SELECT p FROM parent p"
{id=1,subfield=null}
{id=2,subfield=null}
Is it possible to accomplish what I want with this object model, or do I need to get a bit more creative (this is a legacy database, changing the schema is not preferred)
With Hibernate we can use the @Embeddable annotation to mark a class to be eligible as an embeddable class. We can use the @Embedded annotation to embed an embeddable class. The attributes of an embedded class can be overridden using the @AttributeOverrides and the @AttributeOverride annotations.
Entity inheritance means that we can use polymorphic queries for retrieving all the subclass entities when querying for a superclass. Since Hibernate is a JPA implementation, it contains all of the above as well as a few Hibernate-specific features related to inheritance.
The EmbeddedId annotation is applied to a persistent field or property of an entity class or mapped superclass to denote a composite primary key that is an embeddable class. The embeddable class must be annotated as Embeddable .
An @Embedded field cannot contain Primary Key. If a Primary Key needs to be set as auto-generated, a single Primary Key may be used and defined as auto-generated in the @Entity data class.
As pointed by the asker, hibernate does not support inheritance of embeddable classes (https://hibernate.atlassian.net/browse/HHH-1910).
According to the Eclipse wiki, the JPA does not specify this behavior, but EclipseLink does support it (http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Entities/Embeddable#Inheritance).
My suggestion is to smash the class hierachy entirely inside Subfield. Horrible, but should work until this is solved.
Ok you can't easily change the schema, but how about adding a couple of views?
I know this is old.
One way around this is as specified above. Create a view. You say you don't want to change the schema. Then don't. You can create a new schema which maps the old schema and does what you want. (Possibly depending on database)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With