Как сопоставить коллекцию каждого подкласса из одной иерархии с одним классом-владельцем?

Кто-нибудь знает, как сопоставить коллекцию каждого подкласса из одной и той же иерархии с одним классом-владельцем, используя аннотации JPA 2.0, поддерживаемые Hibernate 4.0.0.Final?

Немного запутанно, так что вот пример. Классы иерархии выглядят так:


    @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;

Все это выглядит нормально, и когда я сохраняю объекты, я вижу, как они попадают в базу данных с правильными дискриминаторами и правильным владельцем.

Вот мой «владеющий» класс — ничего особенного в его аннотациях:

@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: Объект с идентификатором: gM4pnnoRge4Odx4lUTZNMQ не принадлежит к указанному подклассу: my.package.SubClassTwo (загруженный объект относится к неправильному классу my.package.SubClassOne) в org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader. java:1420) [hibernate-core-4.0.0.Final.jar:4.0.0.Final] в org.hibernate.loader.Loader.getRow(Loader.java:1373) [hibernate-core-4.0.0.Final .jar:4.0.0.Final] в org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:640) [hibernate-core-4.0.0.Final.jar:4.0.0.Final] в org.hibernate. loader.Loader.doQuery(Loader.java:856) [hibernate-core-4.0.0.Final.jar:4.0.0.Final] в 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. Плавник в org.hibernate.loader.Loader.loadCollection(Loader.java: 2175) [hibernate-core-4.0.0.Final.jar:4.0.0.Final] в org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:61) [hibernate-core-4.0.0.Final .jar:4.0.0.F в org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:622) [hibernate-co в org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEvent в org.hibernate. internal.SessionImpl.initializeCollection(SessionImpl.java:1606) [hibernate-core-4.0.0.Final.jar:4.0.0.Final] в org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:379) [hibernate-c в org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:112) [hibernate-core-4. в org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:266) [hibernate-core-4.0.0.Final.jar:4.0.0.Final]

Я бы хотел, чтобы getSubClassOnes() возвращал коллекцию, содержащую те, которые связаны с владельцем с классом SubClassOnes, а getSubClassTwos() возвращает коллекцию с соответствующими SubClassTwos. Кто-нибудь знает, как я могу этого добиться?


person Ben Kirby    schedule 08.11.2012    source источник


Ответы (1)


Для нас это было исправлено добавлением атрибута targetEntity к аннотации @OneToMany, указывающей на суперкласс, например так:

@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;
person Geert    schedule 15.10.2014