如何修复hibernate警告(HHH000470)?
有时,我得到这个警告信息:
aug 09,2017 3:40:02 AM org.hibernate.collection.internal.AbstractPersistentCollection setCurrentSession 警告:HHH000470:为集合定义了意外会话,但该集合未连接到该会话。 持久集合一次只能与一个会话相关联。 覆盖会话。 收集:[royaleserver.database.entity.PlayerEntity.homeChests#1757]
PlayerEntity:
public class PlayerEntity implements Identifiable, Serializable { ... @OneToMany(mappedBy = "player") private Set homeChests = new HashSet(); public Set getHomeChests() { return homeChests; } public PlayerEntity setHomeChests(Set 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已关闭 在org.hibernate.internal.AbstractSharedSessionContract.checkOpen(AbstractSharedSessionContract.java:337) 在org.hibernate.engine.spi.SharedSessionContractImplementor.checkOpen(SharedSessionContractImplementor.java:135) 在org.hibernate.internal.AbstractSharedSessionContract.checkOpenOrWaitingForAutoClose(AbstractSharedSessionContract.java:343) 在org.hibernate.internal.SessionImpl.getPersistenceContext(SessionImpl.java:2275) ...
有什么问题?
如果您在两个线程中管理持久化对象,混合从两个不同会话收集的对象,或者如果您将对象添加到瞬态对象上的集合并稍后尝试保存它(可能是不同的消息,则通常会发生此类错误虽然)。
在所有情况下,它归结为不正确的会话管理。
你的问题是这个代码:
public PlayerEntity setHomeChests(Set 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管理会话或实体管理器的一些最佳实践。
- Hibernate参数值与预期类型不匹配
- java.lang.NoSuchMethodException:org.hibernate.validator.ClassValidator Seam weblogic 10.3
- 截断所有表的简单方法,清除一级和二级hibernate缓存?
- onSave()(用于使用Hibernate / Spring Data Repositories保存的任何实体)
- 如何使用Hibernate进行投影分组
- Hibernate命名查询顺序依据参数
- 在Hibernate中调用存储过程
- 使用jackson将双向JPA实体序列化为JSON
- 即使在一对多关系中使用orphanRemoval = true,孤儿仍保留在数据库中(JPA / Hibernate)