Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate Embeddable Inheritance

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)

like image 890
Steve Skrla Avatar asked May 27 '09 20:05

Steve Skrla


People also ask

What is embeddable in Hibernate?

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.

What is Hibernate inheritance?

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.

What is embedded ID in Hibernate?

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 .

Can embedded class be used as primary key?

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.


3 Answers

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.

like image 141
Thiago Chaves Avatar answered Sep 22 '22 00:09

Thiago Chaves


Ok you can't easily change the schema, but how about adding a couple of views?

like image 44
James L Avatar answered Sep 21 '22 00:09

James L


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)

like image 25
AixNPanes Avatar answered Sep 21 '22 00:09

AixNPanes