JPA(与Hibernate)@ManyToMany @JoinTable关系级联

时间:2014-02-27 02:07:57

标签: java hibernate jpa

有一种方法可以使用@jointable映射多对多关系,并避免连接行的自动级联?

@ManyToMany注释的级联属性用于创建/合并/删除相关实体(不是连接表的行),并忽略@JoinTable中的可插入/可更新的joincolumns / inversejoincolumns属性。我坚持/合并拥有的关系实体。

示例:在User(所有者)x Role(mappedby)关系中,当我将具有Role集合的User合并为空时,表USER_ROLE的所有行都将被删除用户。

事先提前。


这就是我的观点:

为了简化问题,让我们假设我有一个具有三个属性的用户实体:id,email和一组角色(所有者,@ manytomany,@ jointable)。 我将合并一个至少有一个或多个角色的User实体,而不通过entityManager找到它:

User user = new User(); //detached
user.setId(1L); // for merge
user.setEmail("newemailaddress@example.com");

entityManager.merge(user);

数据库中的结果是:

UPDATE user... /*ok!*/
delete from user_role where ... /* I'd like to avoid it! */

1 个答案:

答案 0 :(得分:1)

我认为,问题在于您正在尝试合并detached entity。如果是这样,分离的实体不再存在于相同的会话中。当您合并它时,您创建新实例并尝试从先前的托管实例(不再是托管实体,因为它是分离的实体)复制状态,因此您将获得一个空state和hibernate删除此对象,因为它是空的。您需要从会话中获取您的托管实体,然后执行 merge 。这只是我的猜测。

编辑:

您的实体是级联的。这些实体的结果显示在user_role中。假设您使用某些角色集合持久保存User(ID = 30L)。现在,您在UI中处理了这个分离的对象,并且由于某些情况需要merge()。如果是这样,您只需使用相同类型和相同PK创建新实例(在您的UI中为它设置一些新状态(通常您不创建它,您只需通过id从会话范围获取它)。当您尝试执行它,hibernate尝试查找具有相同标识的对象。

  1. 如果找到它,只需在表格中更新它。

  2. 如果不是,它会在您的表格中创建一个新的。

    所以我认为你的版本是第一个。