我有一個實體懶惰地初始化一個集合,我也已經將PropertyChangeSupport添加到該實體類。這裏的制定者如何看起來像設置:Hibernate延遲加載的集合和PropertyChangeSupport
public void setAskPrices(Set<AskPrice> askPrices) {
propertyChangeSupport.firePropertyChange(ASKPRICES_PROPERTY, this.askPrices,
this.askPrices = askPrices);
}
在我的代碼中一些其他的問題,我建立一個標準查詢,我希望它急切地獲取這個集合:
List<PriceRequest> pr = session.createCriteria(PriceRequest.class)
.setFetchMode("askPrices", FetchMode.JOIN)
.add(Restrictions.ilike("reqNum", "%" + reqNum + "%")).list();
當我運行上面的查詢,我在Hibernate中得到一個異常:
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:122)
at org.hibernate.collection.PersistentSet.size(PersistentSet.java:162)
at java.util.AbstractSet.equals(AbstractSet.java:75)
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:273)
at com.frc_agencies.model.persistent.PriceRequest.setAskPrices(PriceRequest.java:160)
周圍挖掘後,我發現,在中的firePropertyChange()函數CAL ls oldValu.equals(newValue)。在我的情況下,newValue是新的持久集合。在某些點上的equals()函數調用的新集,後者又調用org.hibernate.collection.AbstractPersistentCollection.readSize(),它看起來像這樣大小():
protected boolean readSize() {
if (!initialized) {
if (cachedSize!=-1 && !hasQueuedOperations()) {
return true;
}
else {
throwLazyInitializationExceptionIfNotConnected();
CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);
CollectionPersister persister = entry.getLoadedPersister();
if (persister.isExtraLazy()) {
if (hasQueuedOperations()) {
session.flush();
}
cachedSize = persister.getSize(entry.getLoadedKey(), session);
return true;
}
}
}
read();
return false;
}
異常被拋出時throwLazyInitializationExceptionIfNotConnected()。 它調用下面的方法:
/**
* Is the collection currently connected to an open session?
*/
private final boolean isConnectedToSession() {
return session!=null &&
session.isOpen() &&
session.getPersistenceContext().containsCollection(this);
}
它返回上session.getPersistenceContext假()containsCollection(本);。 因此,出於某種原因,此時持久性收集不是當前會話的一部分。
我決定做一個實驗。我刪除的標準查詢調用setFetchMode()調用和查詢調用返回後簡單,我叫:
Hibernate.initialize(pr.getAskPrices());
而且似乎做工精細!
但我不想一直調用Hibernate.initialize()。任何人都可以建議我可能做什麼使這個工作使用我原來的setFetchMode()調用?
謝謝。
編輯: 發佈有關映射
<set name="askPrices" table="ASK_PRICE" inverse="true" lazy="true" fetch="select" cascade="all-delete-orphan">
<meta attribute="bound">ASKPRICES_PROPERTY</meta>
<key on-delete="cascade">
<column name="REQ_ID" not-null="true" />
</key>
<one-to-many class="AskPrice" />
</set>
請張貼您的映射XML(或註釋)。另外,看看這個錯誤報告。 https://hibernate.onjira.com/browse/HHH-3524 – zmf
我發佈了相關映射。即使我沒有對實際關聯(僅限於父對象)添加任何限制,該錯誤似乎也是相關的。 – Caleb