我有一个实体懒惰地初始化一个集合,我也已经将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