Java JPA(带Hibernate)@ManyToMany@JoinTable关系级联

Java JPA(带Hibernate)@ManyToMany@JoinTable关系级联,java,hibernate,jpa,Java,Hibernate,Jpa,有一种方法可以使用@jointable映射多对多的关系,并避免jointable行的自动级联 @ManyToMany注释的级联属性用于创建/合并/删除相关实体(而不是jointable的行),并且当我持久化/合并关系的拥有实体时,@jointable中的JointColumns/InverseJointColumns属性的可插入/可更新被忽略 示例:在User(Owner)xRole(mappedby)关系中,当我将一个用户与Role empty集合合并时,该用户的表User\u Role的所有

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

@ManyToMany
注释的级联属性用于创建/合并/删除相关实体(而不是jointable的行),并且当我持久化/合并关系的拥有实体时,
@jointable
中的JointColumns/InverseJointColumns属性的可插入/可更新被忽略

示例:在
User
(Owner)x
Role
(mappedby)关系中,当我将一个用户与Role empty集合合并时,该用户的表
User\u Role
的所有行都将被删除

请提前通知我


这就是我的观点:

为了简化问题,让我们假设我有一个用户实体,它有三个属性:id、email和一组角色(owner、@manytomy、@jointable)。 我将合并至少具有一个或多个角色的用户实体,而不通过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! */

我认为,问题是您正在尝试合并一个
分离的实体
。如果是这样,分离的实体将不再位于您将其持久化的同一会话中。合并该对象时,您将创建新实例,并尝试从以前的托管实例复制状态(因为它是分离的实体,所以不再是托管实体),这样您将获得一个空状态,并且hibernate将删除此对象,因为它是空的。您需要从会话中获取托管实体,然后进行合并。这只是我的猜测

编辑:

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

  • 如果找到它,它只需在表中更新它

  • 如果否,它将在表中创建一个新的

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


  • 非常感谢您的回复。我将在帖子中编辑我的问题problem@Tiago因此,您尝试将您的用户与数据库中的另一个用户合并?这是一个示例。如果我使用角色持久化一个用户,则会填充表用户_角色。我希望避免jointable的级联。如何避免它?当您使用merge()时这意味着,如果满足两个条件:类型标识和PK,则将分离的实体转换为托管实体。因此,如果hibernate找到这些参数,并且它将与新分离的实体相同,那么它将在关系表中简单地更新它。:)因此,这是真的,您需要从已持久化的实体中设置PK other,当您尝试合并它时,hibernate尝试为它查找托管实体,如果找不到,它只会在表中创建一个新实体。:)是的,但在另一种关系中,如ManyToOne,使用@JoinColumn,我可以将Updateable=false设置为可更新,并避免对其进行更新。在resume中,当我持久化或合并关系的所有者实体时,我不想将关系作为实体的一部分进行更新。我没有找到一种方法,所以我把这个问题贴在这里,以检查它是否有意义,是否有人有这样做的想法。你认为这没有道理吗?换言之:始终保持/合并具有多个关系的所有者实体—它将保持该关系。谢谢你的关注:)非常感谢你的回复。我用一个例子更新了这个问题来解释我的观点。谢谢你的帮助。每次我需要合并这个实体时,我必须从上下文(find)中获取它,更新我想要合并的字段并合并实体。我不能简单地实例化它并设置PK。如果我需要更新关系,我可以简单地加载它,删除我想删除的条目,并添加我想包含的实例。