简体   繁体   English

Hibernate 复合钥匙带复合钥匙

[英]Hibernate composite key with composite key

I'm currently mapping a complex database schema wqith HIbernate and I have hit a wall with an entity which has a composite key with another composite key.我目前正在映射一个复杂的数据库模式 wqith HIbernate 并且我遇到了一个实体,该实体具有一个复合键和另一个复合键。

I have this table for roles with a composite key (site_id, id)我有这个表用于具有复合键(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
);

And I have this table with a composite key which also uses the previous one.我有这张表,它有一个复合键,它也使用前一个。

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
);

My current mapping for the roles one which is working is:我当前对正在工作的角色的映射是:

@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;

}

I was trying something similar with the composite Key for the UserSiteRole but Hibernate tells me that it needs to columns to map the roleId when in the table I have just the id but the PK is form by the two values as you can see in the script, not sure how to map it to be honest.我正在尝试与 UserSiteRole 的复合键类似的东西,但 Hibernate 告诉我它需要列到 map 的 roleId 当在表中我只有 id 但 PK 是由两个值形成的,正如您在脚本中看到的那样,说实话,不确定如何 map。

@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;

}

I would appreciate any ideas about how to map it, I had never had to map such a complex relationship so not sure how to proceed in this case.我将不胜感激有关如何 map 它的任何想法,我从来没有对 map 如此复杂的关系,所以不知道在这种情况下如何进行。

Does this answer your question?这回答了你的问题了吗? jpa hibernate composite foreign key mapping jpa hibernate 复合外键映射

Actually that was useful as it made it clear that we could change the mapping from embeddedId to IdClass and make it work.实际上这很有用,因为它清楚地表明我们可以将映射从 embeddedId 更改为 IdClass 并使其工作。

This is our new IdClass, pretty simple:这是我们的新 IdClass,非常简单:

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

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

And the entity itself working just inf e is as follows.实体本身在 inf e 中工作如下。

@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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM