Java Spring JPA保存已存在的@OneToMany关系实体

Java Spring JPA保存已存在的@OneToMany关系实体,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我有2个实体(我删除了无用字段): 当我第一次通过crudepository保存ApkPermissions实体时,我没有问题,但是当我使用权限表中已经存在的某个权限保存另一个ApkPermissions时,会引发一个异常,指示permissionName的唯一键冲突 我找到了这个解决方案: 这似乎适合我的情况(也是我当前的实现),但它不起作用 我收到以下错误消息: could not execute statement; SQL [n/a]; constraint [UK_l3pmqryh8

我有2个实体(我删除了无用字段):

当我第一次通过crudepository保存ApkPermissions实体时,我没有问题,但是当我使用权限表中已经存在的某个权限保存另一个ApkPermissions时,会引发一个异常,指示permissionName的唯一键冲突

我找到了这个解决方案:

这似乎适合我的情况(也是我当前的实现),但它不起作用

我收到以下错误消息:

could not execute statement; SQL [n/a]; constraint [UK_l3pmqryh8vgle52647itattb9]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",
从mysql:

UNIQUE KEY `UK_l3pmqryh8vgle52647itattb9` (`permission_name`)

临时解决方案是从存储库中按permissionName检索所有相应的权限搜索。然后保存工作正常。
它在逻辑上是正确的,但我希望存在一个更简单的过程…

在OneToMany映射中,您的权限表将有一个额外的列,它将是一个外键,指向您的ApkPermissions。 例如:

ApkPermission           Permission
APK_ID | Name           Permission_ID | Name | APK_ID(FK)
1      | APK1            1            | P1   | 1
                         2            | P2   | 1

因此,您不能从任何其他ApkPermission记录指向相同的权限。假设,如果要在ApkPermission中输入2 | APK2并再次指向P1和P2。除非在权限表中再次输入P1和P2项,否则不能使用一对多关系执行此操作。这将创建重复项。因此,这里有两个选项,要么删除唯一约束(在permissionName上),要么将映射更改为ManyToMany。

在OneToMany映射中,权限表将有一个额外的列,该列将是指向ApkPermissions的外键。 例如:

ApkPermission           Permission
APK_ID | Name           Permission_ID | Name | APK_ID(FK)
1      | APK1            1            | P1   | 1
                         2            | P2   | 1

因此,您不能从任何其他ApkPermission记录指向相同的权限。假设,如果要在ApkPermission中输入2 | APK2并再次指向P1和P2。除非在权限表中再次输入P1和P2项,否则不能使用一对多关系执行此操作。这将创建重复项。因此,这里有两个选项,要么删除唯一约束(在permissionName上),要么将映射更改为ManyToMany。

是否可以包含异常消息的输出?我做到了。请注意,现在我按照@Pardeep的建议更改了关系,您可以包含异常消息的输出吗?我做到了。请注意,现在我更改了关系@Pardeep提示您是对的,正确的关系是很多。。。但当我保存一个ApkPermission时,问题仍然存在,该权限在数据库中已经存在的declaredPermissions中。是否尝试使用manyToMany?在这种情况下,你还需要一个连接表。新条目将进入新的联接表。有很多可用的示例。使用OneToMany,您必须插入新记录。如果你仍然想继续使用OneToMany(这不会被规范化),那么你可以删除permissionName中的唯一约束,因为你会有重复的约束。我建议和很多人一起试试。我想提到的一点是,如果主键为null,hibernate save总是进行插入查询。在这种情况下,请使用saveOrUpdate。但是如果你的记录在数据库中,那么当你试图持久化它时,ID不应该为空,否则它总是会假定它是一个新记录。是的,现在我使用的是多个关系,但是如果它们已经存在于数据库中,我必须获取权限。你是对的,正确的关系是多个。。。但当我保存一个ApkPermission时,问题仍然存在,该权限在数据库中已经存在的declaredPermissions中。是否尝试使用manyToMany?在这种情况下,你还需要一个连接表。新条目将进入新的联接表。有很多可用的示例。使用OneToMany,您必须插入新记录。如果你仍然想继续使用OneToMany(这不会被规范化),那么你可以删除permissionName中的唯一约束,因为你会有重复的约束。我建议和很多人一起试试。我想提到的一点是,如果主键为null,hibernate save总是进行插入查询。在这种情况下,请使用saveOrUpdate。但是,如果您的记录在数据库中,那么当您尝试持久化它时,ID不应为null,否则它将始终假定它是一个新记录。是的,现在我使用了多个关系,但是如果它们已经存在于数据库中,我必须获取权限
ApkPermission           Permission
APK_ID | Name           Permission_ID | Name | APK_ID(FK)
1      | APK1            1            | P1   | 1
                         2            | P2   | 1