首页 文章

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

提问于
浏览
0

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

@ManyToMany 注释的cascade属性用于创建/合并/删除相关实体(不是jointable的行),并且当我持久化并合并拥有的关系实体时, @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 回答

  • 1

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

    编辑:

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

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

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

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

相关问题