2012-02-11 89 views
2

我有一個Person類映射到PERSON表和Address類映射到ADDRESS表。我想要的是每個Person兩個列表Address es:homeAddressesofficeAddresses。該ADDRESS表有一個外鍵字段,PERSONID,對於這兩種情況,但它有兩個單獨的列表索引字段:home_add_idxhomeAddresses屬於記錄和off_add_idxofficeAddresses屬於記錄。對於任何給定的ADDRESS記錄,這些列表索引字段中的一個將是NULL。這完全適用於插入,但是當我嘗試檢索記錄時,出現異常,「集合的空索引列」。 (下面全堆棧跟蹤。)在休眠中使用多個列表

我該怎麼做?

Person.java:

public class Person implements Serializable { 
    private String personId; 
    private String personName; 
    private List<Address> homeAddresses = new ArrayList<Address>(); 
    private List<Address> officeAddresses = new ArrayList<Address>(); 

    public String getPersonId() { return personId; } 
    public void setPersonId(String s) { personId = s; } 
    public String getPersonName() { return personName; } 
    public void setPersonName(String s) { personName = s; } 
    public List<Address> getHomeAddresses() { return homeAddresses; } 
    public void setHomeAddresses(List<Address> L) { homeAddresses = L; } 
    public List<Address> getOfficeAddresses() { return officeAddresses; } 
    public void setOfficeAddresses(List<Address> L) { officeAddresses = L; } 
} 

Address.java:

public class Address implements Serializable { 
    private String id; 
    private String houseNo; 
    // [SNIP - street, city, country] 
    private String postalCode; 

    public String getId() { return id; } 
    public void setId(String s) { id = s; } 
    public String getHouseNo() { return houseNo; } 
    public void setHouseNo(String s) { houseNo = s; } 
    // [SNIP - getters for street, city, country] 
    public String getPostalCode() { return postalCode; } 
    public void setPostalCode(String s) { postalCode = s; } 
} 

Person.hbm.xml:

<hibernate-mapping> 
<class name="com.nadhi.list.test.Person" table="PERSON"> 
    <id name="personId" type="java.lang.String"> 
     <column name="PERSONID" /> 
     <generator class="assigned" /> 
    </id> 
    <property name="personName" type="java.lang.String"> 
     <column name="PERSONNAME" /> 
    </property> 
    <list name="homeAddresses" inverse="false" table="ADDRESS" lazy="false" cascade="all"> 
     <key> 
      <column name="PERSONID"/> 
     </key> 
     <list-index column="home_add_idx"></list-index> 
     <one-to-many class="com.nadhi.list.test.Address" /> 
    </list> 
    <list name="officeAddresses" inverse="false" table="ADDRESS" lazy="false" cascade="all"> 
     <key> 
      <column name="PERSONID"/> 
     </key> 
     <list-index column="off_add_idx"></list-index> 
     <one-to-many class="com.nadhi.list.test.Address" /> 
    </list> 
</class> 
</hibernate-mapping> 

Address.hbm.xml:

<hibernate-mapping> 
<class name="com.nadhi.list.test.Address" table="ADDRESS"> 
    <id name="id" type="java.lang.String"> 
     <column name="ID" /> 
     <generator class="assigned" /> 
    </id> 
    <property name="houseNo" type="java.lang.String"> 
     <column name="HOUSENO" /> 
    </property> 
    <!-- [SNIP - mappings for street, city, country] --> 
    <property name="postalCode" type="java.lang.String"> 
     <column name="POSTALCODE" /> 
    </property> 
</class> 
</hibernate-mapping> 

當我插入數據,我插入一個獨立的家庭和辦公室的地址爲同一人。它插入正確。然而,當我嘗試檢索Person對象,我得到以下異常:

org.hibernate.HibernateException: null index column for collection: com.nadhi.list.test.Person.officeAddresses 
at org.hibernate.persister.collection.AbstractCollectionPersister.readIndex(AbstractCollectionPersister.java:770) 
at org.hibernate.collection.PersistentList.readFrom(PersistentList.java:402) 
at org.hibernate.loader.Loader.readCollectionElement(Loader.java:1156) 
at org.hibernate.loader.Loader.readCollectionElements(Loader.java:774) 
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:622) 
at org.hibernate.loader.Loader.doQuery(Loader.java:829) 
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274) 
at org.hibernate.loader.Loader.loadCollection(Loader.java:2166) 
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:62) 
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:627) 
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:83) 
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1863) 
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:479) 
at org.hibernate.engine.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:900) 
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:279) 
at org.hibernate.loader.Loader.doList(Loader.java:2533) 
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276) 
at org.hibernate.loader.Loader.list(Loader.java:2271) 
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119) 
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716) 
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347) 
at org.hibernate.impl.CriteriaImpl.uniqueResult(CriteriaImpl.java:369) 
at com.nadhi.list.test.Main.getPerson(Main.java:113) 
at com.nadhi.list.test.Main.main(Main.java:36) 

在數據庫中,我可以看到,對於家庭地址,辦公地址列索引是空的;而對於辦公地址,家庭地址列索引是空的。但是這不是預期的嗎?爲了正確檢索數據,我需要做什麼?

回答

2

我認爲你需要用兩個獨立的外鍵字段替換ADDRESS.PERSONID外鍵字段—一個用於家庭地址,一個用於辦公地址。

列表索引字段可以保留原樣,也可以將它們合併到單個字段中,也可以完全刪除它們並使用<bag>而不是<list>映射。 (很顯然,如果你不關心列表中地址的順序,最後一種方法是很好的;我不知道你是否這麼做)。

當你考慮它—它是有道理的,索引列沒有達到你想要的。該列僅用於列表(不是集合和行李),所以它不是一種通用的方式來指示記錄屬於哪個集合。所以它是有道理的,它只用於爲已經被確定屬於正確集合的記錄指定列表索引。

+0

這工作。我爲每個列表添加了一個單獨的外鍵字段。非常感謝。 – user163114 2012-02-11 20:00:20

+0

@ user163114:不客氣! – ruakh 2012-02-11 20:00:40