【问题标题】:How to create a composite key of one foreign key and one primary key Spring Data JPA如何创建一个外键和一个主键的复合键 Spring Data JPA
【发布时间】:2022-01-28 06:40:21
【问题描述】:

我正在使用 Spring Boot 来构建 API。它是惩罚系统的 API。在数据库中有两个用于规则的表,它们是规则表和社区表。

规则 ID 是一个整数,社区 ID 是来自社区表的外键。一个社区应该有 0 条、1 条或许多条规则,而一条规则仅由一个社区制定。

这是我希望在我的 Spring Boot 应用程序中复制的行为。

到目前为止,我有以下代码:

社区.java

@Entity // Maps to database
public class Community {
    @Id
    @Column(name = "id", length = 16, unique = true, nullable = false)
    private UUID id;

    @Column(name = "username", length = 20, nullable = false)
    private String name;

Rule.java

@Entity // Maps to database
public class Rule {

    @EmbeddedId
    private RuleId ruleId;

    @Column(name = "description", length = 50, nullable = false)
    private String description;

RuleId.java

@Embeddable
public class RuleId implements Serializable {

    private UUID communityId;
    private Integer ruleId;

    public RuleId(UUID communityId, Integer ruleId) {
        this.communityId = communityId;
        this.ruleId = ruleId;
    }

我已经阅读了堆栈上的一些线程,这是我从中获得嵌入式想法的地方,但我仍然对如何让它与我的场景一起工作感到困惑。非常感谢任何帮助以消除这种混乱。

干杯:)

【问题讨论】:

    标签: java spring spring-data-jpa


    【解决方案1】:

    您可以使用注释@JoinColumn(...) 并指定关系,在您的情况下:@OneToOne(...)

    然后您可以仅使用 Long id 或 int id 来简单地定义您的 Rule 实体,并将其定义为:

    @Entity
    public class Rule {
        
        @Id // map as id field
        @GeneratedValue(strategy = GenerationType.AUTO) // Auto generate id when update db
        @Column(name = "Rule_Id") // map the column field
        private Long ruleId;
        
        // Simply add annotation to map foreign key
        @OneToOne
        @JoinColumn(name = "community_id_fk", referencedColumnName = "community_id")
        private Community community;    
    
        // more field ...
        @Column(name = "description", length = 50, nullable = false)
        private String description;
    }
    

    更多指导可以看https://www.baeldung.com/jpa-one-to-one

    【讨论】:

    • 这是否意味着我的主键是 ruleId 和 communityId 的组合键?因为 ruleId 可以被每个拥有 1 到 10 条规则的社区重用。社区 ID 将使每个规则的记录唯一。
    【解决方案2】:

    我通过 Zukaru 的回答中的一对一关系解决了这个问题。

    我想要的是一个由community_id 和rule_id 组成的组合键。社区 ID 是 Communities 表上主键的外键。

    为了实现这一点,我有 2 个类。 Rule 和 RulePrimaryData。

    Rule.java

    @Entity // Maps to database
    @Table(name = "rules")
    @Data
    @NoArgsConstructor
    public class Rule {
    
        @EmbeddedId
        private RulePrimaryData id;
    
        @OneToOne
        @JoinColumn(name = "community_id_fk", referencedColumnName = "community_id", insertable = false, updatable = false)
        private Community communities;
    
        @Column(name = "description", length = 50, nullable = false)
        private String description;
    
        public Rule(RulePrimaryData ruleId, String description) {
            this.id = ruleId;
            this.description = description;
        }
    }
    

    嵌入的 Id 用于制作包含 UUID 和 Integer 的复合键。

    RulePrimaryData.java

    @Embeddable
    @NoArgsConstructor
    @Data //Getters, setters, constructors
    public class RulePrimaryData implements Serializable {
    
        @Column(name = "community_id_fk", nullable = false)
        private UUID communityId;
    
        @Column(name = "rule_id", nullable = false)
        private Integer ruleId;
    
        public RulePrimaryData(UUID communityId, int ruleId) {
            this.communityId = communityId;
            this.ruleId = ruleId;
        }
    }
    

    最后,这种关系是一对一的,我最初认为是多对一。在定义中,我将 EmbeddedId 中的 community_id_fk 列连接到 Communities 表中的 community_id 列。

    【讨论】:

      猜你喜欢
      • 2020-04-28
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 2015-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多