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

我很难弄清楚如何在某个数据库设计上正确执行 ORM。

我的架构由三个表组成:用户表、评论表和投票表。用户可以发布对相册的评论,还可以对任何评论进行正面或负面的评分。相册是从外部 API 提供的,因此架构中缺少它们的表,但引用了它们的 ID。

用户主键仅由他们的用户名组成。评论主键由评论者的用户名(即外键)和评论的相册 ID 组成。最后,投票主键由投票者的用户名、外键和投票评论的主键组成,如前所述,投票主键由评论者的用户名和评论的相册 ID 组成。

用户可以为每个单独的专辑发布评论,也可以为每个单独的评论分配投票。

这是表示架构的 ER 模型:

https://img1.sycdn.imooc.com/653134400001e61003990400.jpg

为了映射实体 ID,我使用了注释@IdClass,但我不确定我是否朝着正确的方向前进。我也尝试过使用@EmbeddedId注释,但结果是一样的。


这是我的实体类到目前为止的样子:


@Entity

public 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


}



慕丝7291255
浏览 105回答 1
1回答

慕森卡

这些关系是“派生身份”;因此您的 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更干净,消除了实体及其密钥中重复的代码。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java