2012-10-23 65 views
1

Hibernate有沒有可能做下面的實體結構?如何使用Hibernate映射Map <Class,AbstractEntity>之類的屬性?

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

一種解決方法可以用「簡單」的收集和灌裝帶有攔截器的地圖,但我希望有可能實現這一點,而無需額外的基礎設施。

回答

0

的問題主要在我看來,那Hibernate需要依靠一個永久性屬性地圖鍵。因此,解決方案增加了一個新的屬性的抽象類RersonRole

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

然後,它可以指它在@MapKey註釋在類人:

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

利用這種映射現在hibernate可以在沒有更多基礎設施的情況下填充地圖

這從我的角度來看,大多數優雅的解決方案都有添加持久屬性的缺點,這只是因爲休眠(如果我得到問題的根本原因)才需要。

1

有可能implementingh一個Hibernate UserType其類映射到一個字符串和背部

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

see here for an example UserType

+0

這一項不起作用。但是你的回答指向了一個更簡單的解決方案:向PersonRole添加一個類型屬性「className」,並用getClass()對其進行初始化。有了這個星座,我不需要任何UserType。我應該發佈這個答案嗎? – Markus

+0

是的,其他人可能有類似的用例 – Firo

相關問題