2017-08-09 99 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