1

我是 Hibernate 的新手,并尝试保留一个包含集合的实体。

我有我的类 User,其中包含一个 Set 属性。

class User{

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
   @JoinColumn(name = "user_id", referencedColumnName = "id")
   @Valid
   @Nullable
   public Set<Permission> getPermissions()
   {
      return permissions;
   }
}

当我用一组新的权限更新用户并尝试保存它时,权限再次重置为原始值,所有其他值都被更新,只有没有的权限。

@Transactional(readOnly = false)
   @Override
   public User update(User user)
      entityManager.merge(user);
      entityManager.flush(); 
      entityManager.refresh(user); 
      return user;

我已经阅读了有关传递持久性和分离对象的信息,但我仍然没有让它工作。

任何想法我做错了什么?

4

2 回答 2

2

尝试

@Transactional(readOnly = false)
@Override
public User update(User user)
    return entityManager.merge(user);
}

其他调用是不必要的,并且会使您的代码混乱。并且您忽略 的结果merge(),它是作为参数传递的分离的、保持不变的用户的更新、附加版本。

另外,请注意,由于您在关联上有级联 ALL,因此上述内容不仅会更新用户字段以及与用户关联的权限。它还将合并权限。因此,作为参数传递的用户权限状态将被复制到这些权限的附加版本并保存在数据库中。

于 2012-07-19T12:27:03.363 回答
0

也许您要替换整个系列?我发现最好获取现有集合,并在其上调用 .add() 和 .remove() 以更新其内容,而不是替换整个内容。

此外,您可以尝试改用 @ElementCollection

@ElementCollection
@CollectionTable(name="PERMISSION",
        joinColumns={@JoinColumn(name="USER_ID")}
)
private Set<Permission> permissions;

唯一需要注意的是 Permission 类必须用@Embeddable 标记,我不相信您可以直接查询权限作为顶级对象(您必须通过用户)。此外,Permission 对象不会有指向其用户的指针。

这是您如何查询它的示例 hql:

 select p from User u join u.permissions p where p.name=?
于 2012-07-19T12:35:00.707 回答