How to map collection of each subclass from same hierarchy onto one owning class?

天涯浪子 提交于 2019-12-06 12:07:20

问题


Does anyone know how to map a collection of each subclass from the same hierarchy onto one owning class, using JPA 2.0 annotations, backed by Hibernate 4.0.0.Final?

Bit convoluted, so here's an example. Hierarchy classes look like this:


    @Entity
    @Cacheable(true)
    @Table(name = "hierarcicals")
    @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(name = "class", discriminatorType = DiscriminatorType.STRING)
    public abstract class MySuperClass {
    ...

    @Entity
    @DiscriminatorValue("SubClassOne")
    public class SubClassOne extends MySuperClass {
    ...

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "owner")
    private Owner owner;

    @Entity
    @DiscriminatorValue("SubClassTwo")
    public class SubClassTwo extends MySuperClass {
    ...

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "owner")
    private Owner owner;

This all looks fine, and when I persist objects, I can see them going into the database with the right discriminators, and the right owner.

Here's my 'owning' class - nothing special about its annotations:

@Entity
@Cacheable(true)
@Table(name = "owner")
public class Owner  {
...
@OneToMany(mappedBy = "owner", fetch = FetchType.LAZY)
private List<SubClassOne> subClassOnes;

@OneToMany(mappedBy = "owner", fetch = FetchType.LAZY)
private List<SubClassTwo> subClassTwos;
...

The 2 List collections have getters. When I call getSubClassOnes(), I get a bag of ALL the associated entities back, as type SubClassOne, even those that have the SubClassTwo discriminator in the database. When I call getSubClassTwos(), I get what appears to be a bag of SubClassTwos, but which, when I iterate over the collection at runtime, blows up with

org.hibernate.WrongClassException: Object with id: gM4pnnoRge4Odx4lUTZNMQ was not of the specified subclass: my.package.SubClassTwo (loaded object was of wrong class class my.package.SubClassOne) at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1420) [hibernate-core-4.0.0.Final.jar:4.0.0.Final] at org.hibernate.loader.Loader.getRow(Loader.java:1373) [hibernate-core-4.0.0.Final.jar:4.0.0.Final] at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:640) [hibernate-core-4.0.0.Final.jar:4.0.0.Final] at org.hibernate.loader.Loader.doQuery(Loader.java:856) [hibernate-core-4.0.0.Final.jar:4.0.0.Final] at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289) [hibernate-core-4.0.0.Final.jar:4.0.0.Fin at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259) [hibernate-core-4.0.0.Final.jar:4.0.0.Fin at org.hibernate.loader.Loader.loadCollection(Loader.java:2175) [hibernate-core-4.0.0.Final.jar:4.0.0.Final] at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:61) [hibernate-core-4.0.0.Final.jar:4.0.0.F at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:622) [hibernate-co at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEvent at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1606) [hibernate-core-4.0.0.Final.jar:4.0.0.Final] at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:379) [hibernate-c at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:112) [hibernate-core-4. at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:266) [hibernate-core-4.0.0.Final.jar:4.0.0.Final]

What I'd like to happen is that getSubClassOnes() returns a collection containing those associated with the owner with class SubClassOnes, and getSubClassTwos() returns a collection with the relevant SubClassTwos. Does anyone know how I can achieve this?


回答1:


For us this was fixed by adding the targetEntity attribute to the @OneToMany annotation, pointing to the super class, like so:

@OneToMany(mappedBy = "owner", fetch = FetchType.LAZY, targetEntity = MySuperClass.class)
private List<SubClassOne> subClassOnes;

@OneToMany(mappedBy = "owner", fetch = FetchType.LAZY, targetEntity = MySuperClass.class)
private List<SubClassTwo> subClassTwos;


来源:https://stackoverflow.com/questions/13295182/how-to-map-collection-of-each-subclass-from-same-hierarchy-onto-one-owning-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!