在 JPA 中的多对多关系中使用组合键

Gar*_*ryF 4 java database-design hibernate jpa

我有以下情况:

  • 用户对象有一组权限对象 ( Set<Permission>)
  • 每个用户可以有零个或多个权限
  • Permission 对象具有三个字段
  • Permission 的三个字段组成了该权限的复合键。
  • 因此,我们希望每个权限在数据库中有一个实例。每个用户都可能拥有相同的权限。
  • 因此,User 对象与 Permission 具有多对多的关系。

问题是:在这种情况下,如何使 Permission 实体成为其自身的组合键?我对在这种多对多关系的背景下执行此操作特别感兴趣。

有任何想法吗?

Art*_*ald 5

1\xc2\xba权限对象具有三个字段

\n\n

2\xc2\xba Permission up 三个字段组成组合键

\n\n

属性主键和复合主键共享相同的列

\n\n

所以你的问题看起来像这样

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

但是不要忘了

\n\n
\n

由于多个属性共享同一列,因此您必须将其中之一定义为 insertable=false、updatable=false。否则,Hibernate 会报告一些错误。

\n
\n\n

\n\n
\n

当您有复合主键时,您必须设置其值。Hibernate不支持自动生成复合主键。

\n
\n\n

如果您不喜欢上面所示的方法,您可以执行以下操作

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

问候,

\n