Hibernate合并不适用于属性作为集合

时间:2012-07-19 12:17:50

标签: java hibernate collections merge

我是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;

我已阅读过传递性持久性和分离对象,但我仍然无法使用它。

任何想法我做错了什么?

2 个答案:

答案 0 :(得分:2)

尝试

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

其他调用是不必要的,会使代码混乱。并且忽略了merge()的结果,{{1}}是已作为参数传递的分离的,未触及的用户的更新的附加版本。

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

答案 1 :(得分: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=?