gpt4 book ai didi

java - Hibernate 延迟加载的集合和 PropertyChangeSupport

转载 作者:行者123 更新时间:2023-11-29 09:19:26 25 4
gpt4 key购买 nike

我有一个延迟初始化 Set 的实体,我还向该实体类添加了 PropertyChangeSupport。下面是 Set 的 setter 的样子:

public void setAskPrices(Set<AskPrice> askPrices) {
propertyChangeSupport.firePropertyChange(ASKPRICES_PROPERTY, this.askPrices,
this.askPrices = askPrices);
}

在我的代码中的其他一些地方,我构建了一个 Criteria 查询,我希望它能够急切地获取这个集合:

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() 函数调用了 oldValu.equals(newValue)。在我的例子中,newValue 是新的持久集。 equals() 函数在某个时候调用新 Set 上的 size(),后者又调用 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(this) 上返回 false;因此出于某种原因,此时持久集合不是当前 session 的一部分。

我决定做一个实验。我删除了 Criteria 查询上的 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>

最佳答案

对我有用的是立即将集合变成另一种类型的集合:

    List listOfObjects =  new ArrayList(aMethod.getASetOfObjects());

我们无法使用旧版本的 Hibernate。所以我的猜测是 Hibernate 代码中有错误。通过立即构造另一个 java 集合,它将对象复制到(非 volatile )物理内存,而不是 hibernate 缓存。

所以原来的问题会变成这样:

    List this.askPrices = new ArrayList(askPrices)

希望这对您有所帮助。

关于java - Hibernate 延迟加载的集合和 PropertyChangeSupport,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7364671/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com