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

时间:2016-06-21 17:05:00

标签: java spring hibernate jpa

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

@Entity
public class ApkPermissions {
    @Id
    @GeneratedValue
    @JsonIgnore
    private Long id;

    @OneToMany
    @Cascade({CascadeType.SAVE_UPDATE})
    private Collection<Permission> declaredPermissions;
}

@Entity
public class Permission {
    @Id
    @GeneratedValue
    @JsonIgnore
    private Long id;

    @Column(unique = true)
    private String permissionName;
}

当我第一次通过CrudRepository保存ApkPermissions实体时我没有任何问题,但是当我使用Permission表中已存在的一些Permission保存另一个ApkPermissions时,会引发异常,指示uniqueName违反了UniqueName。

我找到了这个解决方案:

http://www.mkyong.com/hibernate/cascade-jpa-hibernate-annotation-common-mistake/

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

我收到以下错误消息:

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执行所有相应的权限搜索。然后保存工作正常。 这在逻辑上是正确的,但我希望存在一个更简单的程序...

1 个答案:

答案 0 :(得分:0)

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

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

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