簡體   English   中英

懶惰的集合初始化在hibernate中失敗

[英]Lazy collection initialization fails in hibernate

今天我遇到了hibernate的下一個問題:

我的方法:

@Transactional
public Period getDefault(Team team) {
    Period defaultPeriod = team.getDefaultPeriod();
    List<Period> periods = _periodDAO.getPeriods(team);
        if (!periods.contains(defaultPeriod)) {
            defaultPeriod = periods.get(periods.size() - 1);
        }
    }
    _periodDAO.initializeIssues(defaultPeriod);
    return defaultPeriod;
}

方法initializeIssues:

public void initializeIssues(Period period) {
    if (period.getIssues() != null) {
        Hibernate.initialize(period.getIssues());
    }
}

如果收集包含defaultPeriod,我會收到異常

Caused by: org.hibernate.HibernateException: collection is not associated with any session
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:474)
at org.hibernate.Hibernate.initialize(Hibernate.java:417)

但是,如果我刪除一些行並將方法更改為

@Transactional    
public Period getDefault(Team team) {
    Period defaultPeriod = team.getDefaultPeriod();
    _periodDAO.initializeIssues(defaultPeriod);
    return defaultPeriod;
}

它工作正常。

我調試了第一個示例,並且hibernate會話在整個方法期間沒有關閉。

據我所知,如果會話中的加載對象( 句點中的一個元素)具有與活動會話關聯的集合,並且在對象之前存在( defaultPeriod )也具有相同的關聯 - 它( defaultPeriod )將失去其關聯。

這是真的嗎? 還有誰遇到過同樣的問題?

謝謝你的回答。

據推測,您的Team參數來自另一個事務和另一個Hibernate Session

@Transactional方法返回時, TransactionManager關閉Session ,它執行一些清理並取消設置(設置為null )所有PersistentCollection實例的Session字段。 您的defaultPeriod在其issues字段中包含其中一個。

Hibernate的Hibernate.initialize()強制執行惰性PersistentCollection的初始化,但是具有以下代碼(調用AbstractPersistentCollection#forceInitialization()

    if ( session == null ) {
        throw new HibernateException( "collection is not associated with any session" );
    }

如果您計划在原始@Transactional方法(生成Team的代碼)之外使用issues集合,則需要加載基礎對象。 將其更改為EAGER加載或使用Hibernate.initialize()執行您正在執行的操作。

另一個解決方案是使Session持續時間長於第一個@Transactional的長度,但我沒有詳細說明。 快速google或SO搜索應該提出一些選擇。


這就是正在發生的事情

Period defaultPeriod = team.getDefaultPeriod();

獲取具有id(例如) 42Period對象。 因為它發生在另一個已經關閉的Session中,所以issuesPersistentCollection ,它有一個null Session引用,並且會拋出你得到的Exception

你這樣做

List<Period> periods = _periodDAO.getPeriods(team);

假設List包含一個id為42Period對象,所以if in

   if (!periods.contains(defaultPeriod)) {
        defaultPeriod = periods.get(periods.size() - 1);
   }

沒有被執行。 雖然equals()返回truecontains()也返回true並因為!而變為false ),但對象不一樣。 List的on有一個附加的(非null) Session ,因此可以初始化一個。 但是你的, defaultPeriod持有的那個不能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM