【问题标题】:Hibernate composite key with composite key使用组合键休眠组合键
【发布时间】:2021-11-24 09:46:34
【问题描述】:

我目前正在使用 HIbernate 映射一个复杂的数据库架构,但我遇到了一个实体,该实体具有一个复合键和另一个复合键。

我有这个表用于具有复合键 (site_id, id) 的角色

CREATE TABLE IF NOT EXISTS core.roles
(
    id uuid NOT NULL DEFAULT gen_random_uuid(),
    name character varying(100) NOT NULL,
    is_system_role boolean NOT NULL DEFAULT FALSE,
    site_id uuid NOT NULL,
    created_at timestamp with time zone NOT NULL DEFAULT now(),
    updated_at timestamp with time zone NOT NULL DEFAULT now(),
    created_by uuid NOT NULL,
    updated_by uuid NOT NULL,
    CONSTRAINT roles_pkey PRIMARY KEY (site_id, id),
    CONSTRAINT roles_name_key UNIQUE (site_id, name),
    CONSTRAINT roles_site_id_fkey FOREIGN KEY (site_id)
        REFERENCES core.sites (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE CASCADE,
    CONSTRAINT roles_created_by_fkey FOREIGN KEY (created_by)
        REFERENCES core.users (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE RESTRICT,
    CONSTRAINT roles_updated_by_fkey FOREIGN KEY (updated_by)
        REFERENCES core.users (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE RESTRICT
);

我有这个表,它有一个复合键,它也使用前一个。

CREATE TABLE IF NOT EXISTS core.user_site_roles
(
    user_id uuid NOT NULL,
    site_id uuid NOT NULL,
    role_id uuid NOT NULL,
    created_at timestamp with time zone NOT NULL DEFAULT now(),
    created_by uuid NOT NULL,
    CONSTRAINT user_site_roles_pkey PRIMARY KEY (site_id, user_id, role_id),
    CONSTRAINT user_site_roles_site_id_fkey FOREIGN KEY (site_id)
        REFERENCES core.sites (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE CASCADE,
    CONSTRAINT user_site_roles_role_id_fkey FOREIGN KEY (site_id, role_id)
        REFERENCES core.roles (site_id, id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE CASCADE,
    CONSTRAINT user_site_roles_user_id_fkey FOREIGN KEY (user_id)
        REFERENCES core.users (id) MATCH SIMPLE
        ON UPDATE NO ACTION
   
    CONSTRAINT user_site_roles_created_by_fkey FOREIGN KEY (created_by)
        REFERENCES core.users (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE RESTRICT
);

我当前对正在工作的角色的映射是:

@Embeddable
public class CommonId implements Serializable {

    @Type(type = "pg-id-uuid")
    @Column(columnDefinition = "uuid", updatable = false)
    private UUID id;

    @Type(type = "pg-id-uuid")
    @Column(name = "site_id", columnDefinition = "uuid", updatable = false)
    private UUID siteId;
}

@Entity
@Table(name = "roles", schema = "core")
@Data
@TypeDefs({
        @TypeDef(name = "pg-id-uuid", typeClass = PostgresIdUUIDType.class)
})
public class Role extends AuditAtBy implements Serializable {

    @EmbeddedId
    private CommonId roleId;

    @ManyToOne
    @MapsId("siteId")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Site site;

    @Column(nullable = false, unique = true, length = 100)
    private String name;

    @Column(name = "is_system_role", nullable = false)
    private boolean isSystemRole;

}

我正在尝试使用 UserSiteRole 的复合键进行类似的操作,但 Hibernate 告诉我,当在表中我只有 id 但 PK 是由两个值形成时,它需要列来映射 roleId,如您所见在脚本中,说实话不知道如何映射它。

@Embeddable
public class UserSiteRoleId implements Serializable {

    @Type(type = "pg-id-uuid")
    @Column(columnDefinition = "uuid", updatable = false)
    private UUID userId;

    @Type(type = "pg-id-uuid")
    @Column(name = "site_id", columnDefinition = "uuid", updatable = false)
    private UUID siteId;

    @Type(type = "pg-id-uuid")
    @Column(name = "role_id", columnDefinition = "uuid", updatable = false)
    private UUID roleId;
}

@Entity
@Table(name = "user_site_roles", schema = "core")
@Data
@TypeDefs({
        @TypeDef(name = "pg-id-uuid", typeClass = PostgresIdUUIDType.class)
})
public class UserSiteRole extends AuditCreated implements Serializable {

    @EmbeddedId
    private UserSiteRoleId userSiteRoleId;

    @ManyToOne
    @MapsId("userId")
    @JoinColumn(name = "user_id", columnDefinition = "uuid", nullable = false)
    @Type(type = "pg-id-uuid")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private User user;

    @ManyToOne
    @MapsId("siteId")
    @JoinColumn(name = "site_id", columnDefinition = "uuid", nullable = false)
    @Type(type = "pg-id-uuid")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Site site;

    @ManyToOne
    @MapsId("roleId")
    @JoinColumn(name = "role_id", columnDefinition = "uuid", nullable = false)
    @Type(type = "pg-id-uuid")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Role role;

}

如果有任何关于如何映射它的想法,我将不胜感激,我从来没有绘制过如此复杂的关系,所以不知道在这种情况下如何进行。

【问题讨论】:

标签: java hibernate jpa


【解决方案1】:

这是否回答了您的问题? jpa hibernate复合外键映射

实际上这很有用,因为它清楚地表明我们可以将映射从 embeddedId 更改为 IdClass 并使其工作。

这是我们的新 IdClass,非常简单:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserSiteRoleId implements Serializable {

    private User user;
    private Site site;
    private Role role;
}

而实体本身的工作原理如下。

@Entity
@Table(name = "user_site_roles", schema = "core")
@Data
@TypeDefs({
        @TypeDef(name = "pg-id-uuid", typeClass = PostgresIdUUIDType.class)
})
@IdClass(UserSiteRoleId.class)
public class UserSiteRole extends AuditCreated implements Serializable {

    @Id
    @ManyToOne
    @JoinColumn(name = "user_id", columnDefinition = "uuid", nullable = false)
    @Type(type = "pg-id-uuid")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private User user;

    @Id
    @ManyToOne
    @JoinColumn(name = "site_id", columnDefinition = "uuid", nullable = false)
    @Type(type = "pg-id-uuid")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Site site;

    @Id
    @ManyToOne
    @JoinColumns({
            @JoinColumn(name = "role_id", referencedColumnName="id", columnDefinition = "uuid", insertable = false, updatable = false),
            @JoinColumn(name = "site_id", referencedColumnName="site_id", columnDefinition = "uuid", insertable = false, updatable = false)
    })
    @Type(type = "pg-id-uuid")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Role role;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    相关资源
    最近更新 更多