Is it possible to map (JPA) a Java type hierarchy that uses generalizations in an abstract superclass?

I read a lot of questions about SO and blog posts and JPA mapping documentation, but nothing seems to be clearly relevant to my situation (which surprises me since I'm sure I'm not the first person to want to display a class hierarchy like this )

I have a good, well-thought out object model that I need to map through JPA. It looks like this

public abstract class BaseEntity<T extends BaseEntity> {
    private Integer id;
    private List<T> children;
}

public class ConcreteEntity1 extends BaseEntity<ConcreteEntity2> {
    private String value;
}

public class ConcreteEntity2 extends BaseEntity{
    private String foo;
}

It seems I can’t display it at all. The closest I got is this (now I use XML mapping, although I also tried annotations):

<mapped-superclass class="com.me.datamodel.BaseEntity" access="FIELD">
    <attributes>
        <id name="id">
            <column name="auto_id" nullable="false"/>
            <generated-value strategy="IDENTITY"/>
        </id>
    </attributes>
</mapped-superclass>

<entity class="com.me.datamodel.ConcreteEntity1" access="FIELD">
    <attributes>
        <basic name="value" />
        <one-to-many name="children" fetch="EAGER" mapped-by="media">
            <cascade><cascade-all /></cascade>
        </one-to-many>
    </attributes>
</entity>

<entity class="com.me.datamodel.ConcreteEntity2" access="FIELD">
    <attributes>
        <basic name="foo" />
    </attributes>
</entity>

, JPA children ConcreteEntity1. , children (BaseEntity) . , , "BaseEntity" . children BaseEntity, ConcreteEntity2 ( ConcreteEntity1).

, ? , ( ).

+3
1

, , BaseEntity ConcreteEntity2: , public class ConcreteEntity2 extends BaseEntity<ConcreteEntity2> {...}. - ConcreteEntity2 , , ConcreteEntity1.

, ( EclipseLink 2.5.1 Hibernate 4.3.1.Final):

@MappedSuperclass
public abstract class BaseEntity<T extends BaseEntity> {
    private Integer id;
    private List<T> children;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    @OneToMany(cascade=CascadeType.ALL)
    public List<T> getChildren() {
        return children;
    }
    public void setChildren(List<T> children) {
        this.children = children;
    }
}

@Entity
public class ConcreteEntity1 extends BaseEntity<ConcreteEntity2> {
    private String value;

    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
}
@Entity
public class ConcreteEntity2 extends BaseEntity<ConcreteEntity2> {
    private String foo;

    public String getFoo() {
        return foo;
    }
    public void setFoo(String foo) {
        this.foo = foo;
    }
}

: , JPA , , ( JPA 2.2 ), , ConcreteEntity2 ( , BaseEntity), BaseEntity , , . JPA.

+2

All Articles