Simone Aonzo
Simone Aonzo

Reputation: 921

Spring JPA save an already existing Entity of @OneToMany relationship

I have 2 entities (I removed useless fields):

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

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

and

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

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

when I save the ApkPermissions entity for the first time through a CrudRepository I've no problems, but when I save another ApkPermissions with some Permission that already exists in the Permission table an exception is raised indicating the Unique Key violation of permissionName.

I found this solution:

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

that seems to fit my case (and is my current implementation), but it doesn't work.

I get the following error message:

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

From mysql:

UNIQUE KEY `UK_l3pmqryh8vgle52647itattb9` (`permission_name`)

Temporary solution is retrive all corresponding Permission searching by permissionName from a Repository. Then the save works fine. It's logically correct but I hope that exists a simpler procedure...

Upvotes: 4

Views: 4447

Answers (1)

Pardeep Deswal
Pardeep Deswal

Reputation: 26

In OneToMany mapping, your permission table will have one extra column which will be a foreign key pointing to your ApkPermissions. For Example:

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

So you can not point same permission from any other ApkPermission record. Suppose, if you want to enter 2 | APK2 in ApkPermission and want to point P1 and P2 again. You can not do it with one to many relation unless you make P1 and P2 entry again in permission table. That will create duplicates. So you have two options here, either you drop the unique constraints(on permissionName) or you change the mapping to ManyToMany.

Upvotes: 1

Related Questions