为了账号安全,请及时绑定邮箱和手机立即绑定

如何正确映射主键由两个外键组成的实体,其中一个外键本身是复合的?

如何正确映射主键由两个外键组成的实体,其中一个外键本身是复合的?

慕丝7291255 2023-10-19 21:50:01
我很难弄清楚如何在某个数据库设计上正确执行 ORM。我的架构由三个表组成:用户表、评论表和投票表。用户可以发布对相册的评论,还可以对任何评论进行正面或负面的评分。相册是从外部 API 提供的,因此架构中缺少它们的表,但引用了它们的 ID。用户主键仅由他们的用户名组成。评论主键由评论者的用户名(即外键)和评论的相册 ID 组成。最后,投票主键由投票者的用户名、外键和投票评论的主键组成,如前所述,投票主键由评论者的用户名和评论的相册 ID 组成。用户可以为每个单独的专辑发布评论,也可以为每个单独的评论分配投票。这是表示架构的 ER 模型:为了映射实体 ID,我使用了注释@IdClass,但我不确定我是否朝着正确的方向前进。我也尝试过使用@EmbeddedId注释,但结果是一样的。这是我的实体类到目前为止的样子:@Entitypublic class User implements Serializable {    private static final long serialVersionUID = 1;    @Id @Column(name = "username")    private String username;    @Column(unique = true, nullable = false)    private String email;    @Column(name = "password", nullable = false)    private String password;    @Temporal(TemporalType.TIMESTAMP) @Column(name="signUpDate", nullable = false)    private Date signUpDate;    // empty constructor, getters, setters, equals and hashCode implementations}@Entity @IdClass(ReviewId.class)public class Review implements Serializable {    private static final long serialVersionUID = 1;    @Id @ManyToOne @JoinColumn(name = "reviewerUsername", referencedColumnName = "username")    private User reviewer;    @Id @Column(name = "reviewedAlbumId")    private Long reviewedAlbumId;    @Column(name = "content", nullable = false, length = 2500)    private String content;    @Column(name = "rating", nullable = false)    private Integer rating;    @Temporal(TemporalType.TIMESTAMP) @Column(name = "publicationDate", nullable = false)    private Date publicationDate;    // empty constructor, getters, setters, equals and hashCode implementations}
查看完整描述

1 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

这些关系是“派生身份”;因此您的 ID 类应如下所示(请注意外键字段的类型与其相应实体字段的类型不同):


public class ReviewId implements Serializable {


    private static final long serialVersionUID = 1L;


    private String reviewer; // matches name of @Id attribute and type of User PK

    private Long reviewedAlbumId;


    // ...


}

public static class VoteId implements Serializable {


    private static final long serialVersionUID = 1L;


    private String voter; // matches name of @Id attribute and type of User PK

    private ReviewId review; // matches name of @Id attribute and type of Review PK


    // ...


}

JPA 2.2 规范的第 2.4.1节讨论了派生身份(并附有示例)。

另外,作为旁注,@IdClass它有点老派,但@EmbeddedId更干净,消除了实体及其密钥中重复的代码。


查看完整回答
反对 回复 2023-10-19
  • 1 回答
  • 0 关注
  • 104 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信