1

Hibernateで次のエンティティ構造を実行する可能性はありますか?

@Entity
public class Person {

    @OneToMany
    private Map<Class<? extends PersonRole>, PersonRole> personRoles;

    public <T extends PersonRole> T getRole(Class<T> roleClass) {
         return roleClass.cast(roles.get(roleClass));
    }

}

@Entity
public abstract class PersonRole {

    @ManyToOne
    private Person person;

}

基本的に、Hibernateはこのマップされたエンティティを永続化できますが、次の例外を除いて、データベースからそれをロードすることはできません。

Exception in thread "main" org.hibernate.HibernateException: null index column for      collection: de.his.cs.sys.hibernate.Person.roles
at org.hibernate.persister.collection.AbstractCollectionPersister.readIndex(AbstractCollectionPersister.java:822)
at org.hibernate.collection.internal.PersistentMap.readFrom(PersistentMap.java:277)
at org.hibernate.loader.Loader.readCollectionElement(Loader.java:1189)
at org.hibernate.loader.Loader.readCollectionElements(Loader.java:804)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:655)
at org.hibernate.loader.Loader.doQuery(Loader.java:854)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:293)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:263)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2094)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:61)

回避策は、「単純な」コレクションを使用し、マップをインターセプターで埋めることですが、追加のインフラストラクチャなしでこれを達成できる可能性を期待しています。

4

2 に答える 2

1

UserTypeクラスを文字列にマップして戻すHibernateを実装することが可能です

@OneToMany
@MapKey(name = "className" type=@Type(type="namespace.classToNameUserType"))
private Map<Class<? extends PersonRole>, PersonRole> personRoles;

UserTypeの例については、こちらをご覧ください

于 2012-10-23T11:37:06.627 に答える
0

問題は基本的に私には思えます。休止状態はマップキーの永続属性に依存する必要があるということです。したがって、このソリューションは、抽象クラスRersonRoleに新しい属性を追加します。

private Class<?> className = this.getClass();

次に、Personクラスの@MapKeyアノテーションでそれを参照することができます。

@OneToMany
@MapKey(name = "className")
private Map<Class<? extends PersonRole>, PersonRole> personRoles;

このマッピングにより、Hibernateは追加のインフラストラクチャなしでマップを埋めることができるようになりました。

私の観点からすると、これはほとんどエレガントなソリューションであり、永続属性を追加するという欠点があります。これは、休止状態のためにのみ必要です(問題の根本的な原因を正しく理解した場合)。

于 2012-10-24T07:48:38.473 に答える