使用重复的额外列使多对多休眠

Posted

技术标签:

【中文标题】使用重复的额外列使多对多休眠【英文标题】:Hibernate many to many with extra column that repeats 【发布时间】:2021-08-18 16:13:29 【问题描述】:

所以我想在多对多情况下设置一个带有附加属性的表。

public class Customer 
    private int id;
    // other attributes 
    // constructors
    // getters / setters

public class Product 
    private int id;
    // other attributes 
    // constructors
    // getters / setters

然后我有“访问”类链接前面的 2 个

@Entity
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class Visit 

    @EmbeddedId
    private VisitId visitId = new VisitId();

    @ManyToOne
    @MapsId("customerId")
    @JoinColumn(name = "id_customer", nullable = false)
    private Customer customer;

    @ManyToOne
    @MapsId("productId")
    @JoinColumn(name = "id_product", nullable = false)
    private Product product;

    private LocalDateTime date = LocalDateTime.now();

    @Embeddable
    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public static class VisitId implements Serializable 

        private static final long serialVersionUID = 1L;

        private int customerId;
        private int productId;
    

经过测试 客户 1 与产品 1 客户 2 与产品 1

并将其添加到数据库中。但是,如果我尝试在日期不同时再次将客户 1 与产品 1 添加,则它不起作用,因为主键是 CustomerId 和 ProductId。如何将另一个“private int id”添加到主键或仅将日期转换为主键?

【问题讨论】:

【参考方案1】:

由于复杂的 ID(客户和产品)不是唯一的,因此您可以只使用一个简单的 ID 以及与您指定的表的关系。

@Id
private int visitId

@ManyToOne 
@JoinColumn(name = "id_customer", nullable = false)
private Customer customer;

@ManyToOne
@JoinColumn(name = "id_product", nullable = false)
private Product product;

也许添加一个unique constrain

@Table(
uniqueConstraints=
    @UniqueConstraint(columnNames="id_customer", "id_product", date )
)
@Entity
public class Visit

【讨论】:

谢谢你的答案,我会试试这个。【参考方案2】:

我更喜欢将日期作为主键来尊重领域概念。因此,将日期字段从 Visit 类移动到 VisitId 类:

@Entity
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class Visit 

    @EmbeddedId
    private VisitId visitId = new VisitId();

    @ManyToOne
    @MapsId("customerId")
    @JoinColumn(name = "id_customer", nullable = false)
    private Customer customer;

    @ManyToOne
    @MapsId("productId")
    @JoinColumn(name = "id_product", nullable = false)
    private Product product;

    @Embeddable
    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public static class VisitId implements Serializable 

        private static final long serialVersionUID = 1L;

        private int customerId;
        private int productId;
        private LocalDateTime date = LocalDateTime.now();

    

【讨论】:

以上是关于使用重复的额外列使多对多休眠的主要内容,如果未能解决你的问题,请参考以下文章

如何在休眠/弹簧中更新多对多集合(延迟加载)?

具有额外多对多关系的 JPA 多对多

如何在多对多关系上使用休眠和 JPA 删除孤立实体?

休眠多对多like子句

具有多个多对多关系的休眠批处理事务

休眠双向多对多映射建议!