我在 @Entity User
有以下属性
@OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", cascade=CascadeType.ALL, orphanRemoval = true)
public Set<Friendship> getOwnedFriendships() {
return ownedFriendships;
}
//other side:
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "owner_id")
public User getOwner() {
return owner;
}
代码Set<Friendship> res = currentUser.getOwnedFriendships();
在我的 servlet 中正常工作,直到删除 Friendship
使用 FriendshipDao
从数据库中(通过其他引用 - 不是上面返回的集合中的引用):
@PersistenceContext
protected EntityManager em;
@Override
public void remove(Friendship toRemove) {
if(!toRemove.isNew()) {
em.remove(toRemove);
}
}
随后调用getOwnedFriendships()
无论此时数据库中实际是什么,总是返回相同的(旧)结果。在用户登录/注销之前,这些值不会更新。我如何获得正确且最新的拥有的友谊?
我怀疑 hibernate 属性
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
造成了麻烦,因为“手动”SQL 查询返回最新数据。禁用这个或硬编码 SQL 查询字符串似乎并不能解决问题,因为第一个会导致lazyInitializationException(当前用户在访问 ownedFriendships
时自动分离),而后者意味着绕过 Hibernate 和 Spring(或多或少)这可能是一个糟糕的设计(?) - 我更喜欢配置框架/dao/域而不是任何“手动”解决方案。
编辑:事实证明问题(或问题之一)是 currentUser
存储在 session 中:
public User getCurrentUser(HttpSession session)
{
return session.getAttribute(CURRENT_USER_ATTR);
}
当我重新查询用户时:
public User getCurrentUser(HttpSession session)
{
return userManager.findUserByName((String)session.getAttribute(USERNAME_ATTR));
Set<Friendship> res = currentUser.getOwnedFriendships();
返回了最新的结果。 (在查询任何惰性属性之前是否需要获取新的实体实例?)
最佳答案
当您的实体之间存在双向关系时,您有责任维护双方。因此,您需要先从 User
中删除 Friendship
,然后再从数据库中删除它。试试这个
@Override
public void remove(Friendship toRemove) {
if(!toRemove.isNew()) {
toRemove.getOwner().getOwnedFriendships().remove(toRemove);
em.merge(toRemove.getOwner());
em.remove(toRemove);
}
}
关于java - Hibernate + spring获取最新的lazy 1 to N属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34617747/