2017-08-09 138 views
0

有時候,我得到這個警告信息:如何解決休眠警告(HHH000470)?

 
aug 09, 2017 3:40:02 AM org.hibernate.collection.internal.AbstractPersistentCollection setCurrentSession 
WARN: HHH000470: An unexpected session is defined for a collection, but the collection is not connected to that session. A persistent collection may only be associated with one session at a time. Overwriting session. Collection : [royaleserver.database.entity.PlayerEntity.homeChests#1757] 

PlayerEntity:

public class PlayerEntity implements Identifiable<Long>, Serializable { 
    ... 
    @OneToMany(mappedBy = "player") 
    private Set<HomeChestEntity> homeChests = new HashSet<>(); 

    public Set<HomeChestEntity> getHomeChests() { 
     return homeChests; 
    } 

    public PlayerEntity setHomeChests(Set<HomeChestEntity> homeChests) { 
     this.homeChests = homeChests; 
     return this; 
    } 
} 

HomeChestEntity:

public class HomeChestEntity implements Serializable { 
    @Id 
    @ManyToOne 
    @PrimaryKeyJoinColumn(name = "player_id", referencedColumnName = "id") 
    private PlayerEntity player; 
    ... 
} 

而這個警告信息後,會被關閉。

 
java.lang.IllegalStateException: Session/EntityManager is closed 
    at org.hibernate.internal.AbstractSharedSessionContract.checkOpen(AbstractSharedSessionContract.java:337) 
    at org.hibernate.engine.spi.SharedSessionContractImplementor.checkOpen(SharedSessionContractImplementor.java:135) 
    at org.hibernate.internal.AbstractSharedSessionContract.checkOpenOrWaitingForAutoClose(AbstractSharedSessionContract.java:343) 
    at org.hibernate.internal.SessionImpl.getPersistenceContext(SessionImpl.java:2275) 
    ... 

什麼問題?

+0

你爲什麼刪除答案鉤? – thst

回答

0

如果您在兩個線程中管理持久對象,混合從兩個不同會話收集的對象,或者將對象添加到瞬態對象上的集合並稍後嘗試保存它(通常會發生這種錯誤不過,不同的消息)。

在所有情況下,歸結爲不正確的會話管理。

你的問題是這樣的代碼:

public PlayerEntity setHomeChests(Set<HomeChestEntity> homeChests) { 
    this.homeChests = homeChests; 
    return this; 
} 

您可能替代的關係(在this.homeChests字段)的性質給出的瞬態集。

一個更好的解決辦法是:

if(this.homeChests == null) { 
    this.homeChests = new HashSet<>(homeChests); 
} 
else { 
    // very simply, you possibly better sync the new elements in... 
    this.homeChests.addAll(homeChests); 
} 

該解決方案是同樣的問題,如果你不能保證,這些元素都是新的。您也可能遇到過時的對象。

正如我所說的,您需要注意您的會話處理涵蓋樹上的所有操作。不要在新會話中簡單使用瞬態對象,您需要將它們合併或重新加載。我建議你仔細看看有關hibernate會話處理的stackoverflow問題。另外,hibernate文檔介紹瞭如何使用hibernate管理會話或實體管理器的一些最佳實踐。

+0

你好:) 我在github上發現了我的錯誤。你能向我解釋它是如何被稱爲? [此處爲錯誤示例](https://github.com/hibernate/hibernate-orm/blob/0a2a5c622e3eb30724e80bc8661c0ac55ebfb2be/hibernate-core/src/test/java/org/hibernate/test/collection/multisession/MultipleSessionCollectionWarningTest.java# L70) –

+0

看看評論://現在從PersistenceContext中刪除集合而不會忽略它的會話\t \t //這在實踐中絕不應該這樣做;它在這裏完成只是爲了測試⚠️這個錯誤沒有真名。您可以在會話中將其稱爲臨時收集 – thst