JPA multi-to-many composite key usage

I have the following situation:

  • The user object has Set Permission objects ( Set<Permission> )
  • Each user can have zero or more Permissions
  • The Permission object has three fields
  • The three permission fields make up the composite key for this permission.
  • As a result of this, we want exactly one instance in the database of each resolution. Each user can potentially have the same permission.
  • Thus, the User object has a many-to-many relationship with resolution.

The question is: how do I make the Permission object composite in this situation? I am particularly interested in this in the context of this many-to-many relationship.

Any ideas?

+4
source share
1 answer

1ΒΊ The Permission object has three fields

2ΒΊ Three Resolution fields make up the composite key

Both properties and composite primary keys use the same columns.

So your question is as follows

 @Entity public class Permission { private PermissionId permissionId; private Integer field1; private Integer field2; private Integer field3; // required no-arg constructor public Permission() {} public Permission(Integer field1, Integer field2, Integer field3) { this.field1 = field1; this.field2 = field2; this.field3 = field3; setPermissionId(new PermissonId(Integer field1, Integer field2, Integer field3)); } @EmbeddedId public PermissionId getPermissionId() { return this.permissionId; } @Column(name="FIELD_1", insertable=false, updatable=false) public Integer getField1() { return this.field1; } @Column(name="FIELD_2", insertable=false, updatable=false) public Integer getField2() { return this.field2; } @Column(name="FIELD_3", insertable=false, updatable=false) public Integer getField3() { return this.field3; } @Embeddable public static class PermissionId implements Serializable { private Integer field1; private Integer field2; private Integer field3; // required no-arg constructor public PermissionId() {} public PermissionId(Integer field1, Integer field2, Integer field3) { this.field1 = field1; this.field2 = field2; this.field3 = field3; } @Column(name="FIELD_1", nullable=false) public Integer getField1() { return this.field1; } @Column(name="FIELD_2", nullable=false) public Integer getField2() { return this.field2; } @Column(name="FIELD_3", nullable=false) public Integer getField3() { return this.field3; } public boolean equals(Object o) { if(o == null) return false; if(!(o instanceof PermissionId)) return false; final PermissionId other = (PermissionId) o; if(!(getField1().equals(other.getField1()))) return false; if(!(getField2().equals(other.getField2()))) return false; if(!(getField3().equals(other.getField3()))) return false; return true; } // requered hashcode impl public int hashcode() { // code goes here } } } 

But don't forget

Since more than one property has the same column , you must define one of them as insertable = false, updatable = false. Otherwise, Hibernate will complain about some bugs.

and

When you have a composite primary key, you must set its values. Hibernate does not support the automatic generation of a composite primary key.

But , if you do not like the approach as shown above, you can do the following

 @Entity @IdClass(PermissionId.class) public class Permission { private Integer field1; private Integer field2; private Integer field3; // required no-arg constructor public Permission() {} public Permission(Integer field1, Integer field2, Integer field3) { this.field1 = field1; this.field2 = field2; this.field3 = field3; } @Id @Column(name="FIELD_1", nullable=false) public Integer getField1() { return this.field1; } @Id @Column(name="FIELD_2", nullable=false) public Integer getField2() { return this.field2; } @Id @Column(name="FIELD_3", nullable=false) public Integer getField3() { return this.field3; } @Embeddable public static class PermissionId implements Serializable { private Integer field1; private Integer field2; private Integer field3; // required no-arg constructor public PermissionId() {} public PermissionId(Integer field1, Integer field2, Integer field3) { this.field1 = field1; this.field2 = field2; this.field3 = field3; } @Column(name="FIELD_1") public Integer getField1() { return this.field1; } @Column(name="FIELD_2") public Integer getField2() { return this.field2; } @Column(name="FIELD_3") public Integer getField3() { return this.field3; } public boolean equals(Object o) { if(o == null) return false; if(!(o instanceof PermissionId)) return false; final PermissionId other = (PermissionId) o; if(!(getField1().equals(other.getField1()))) return false; if(!(getField2().equals(other.getField2()))) return false; if(!(getField3().equals(other.getField3()))) return false; return true; } // requered hashcode impl public int hashcode() { // code goes here } } } 

Respectfully,

+4
source

Source: https://habr.com/ru/post/1302970/


All Articles