JPA - 一个实体如何引用多对多关系中涉及的两个其他实体?

Posted

技术标签:

【中文标题】JPA - 一个实体如何引用多对多关系中涉及的两个其他实体?【英文标题】:JPA - How can an entity refer to two other entities involved in a ManyToMany relationship? 【发布时间】:2021-05-12 22:56:39 【问题描述】:

我有以下表格:

在我的域模型中,我有一个Car 实体:

@Entity
@Data
public class Car 

    @Id
    private Long id;

    @ManyToMany
    @JoinTable(name="CarClassType",
        joinColumns= @JoinColumn(name="carId"),
        inverseJoinColumns = @JoinColumn(name="classTypeId"))
    private List<CarType> carTypes;
    
    private String model;

我还有一个 CarClassTypeSaleClassType 实体。我没有CarClassType 实体。 CarClassTypeSale 类应该如何引用 CarClassType

@Entity
@Data
public class CarClassTypeSale 

    @Id
    private Long id;

    @ManyToOne // this doesn't work; errors with invalid column name
    private Car car;

    @ManyToOne // this doesn't work; errors with invalid column name
    private ClassType classType;


【问题讨论】:

【参考方案1】:

此处的建模不需要@ManyToMany,因为您可以将CarClassType 建模为实体。由于CarClassType 表有一个附加列id,因此您实际上也不能以这种方式对其进行建模。如果你想要这个,你必须同时使用这两个 FK 作为主键并删除 id 列,我还是建议你这样做。

@Entity
@Data
public class Car 

    @Id
    private Long id;

    @OneToMany(mappedBy = "car")
    private Set<CarClassType> carTypes;
    
    private String model;

@Entity
@Data
public class CarClassType 

    @EmbeddedId
    private CarClassTypeId id;

    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "carId", insertable = false, updatable = false)
    private Car car;
    
    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "classTypeId", insertable = false, updatable = false)
    private CarType classType;

    @OneToMany(mappedBy = "carClassType")
    private Set<CarClassTypeSale> sales = new HashSet<>();

@Embeddable
@Data
public class CarClassTypeId 

    @Column(name = "carId")
    private Integer carId;
    
    @Column(name = "classTypeId")
    private Integer classTypeId;

@Entity
@Data
public class CarClassTypeSale 

    @Id
    private Long id;

    @ManyToOne
    private CarClassType carClassType;

    private LocalDate soldDate;



不确定CarClassTypeSale 是否适合这张图片。你的图表并没有真正告诉我这个类与其他类的关系。

【讨论】:

感谢您的回答。 CarClassTypeSale 捕获属于特定类别类型的汽车的销售。所以,CarClassTypeSale 指的是CarClassTypeCarClassType 中的一条记录指的是一条Car 和一条ClassType。因此,一个CarClassTypeSale 间接引用了一个Car 和一个ClassType。也许,我误解了你关于它与其他人的关系的说明,但我确实在图表中看到了这种关系。 另外,你能告诉我为什么你更喜欢去掉CarClassTypeid 列吗?我同意如果我们将 FK 设为复合 PK,则不需要它,但 id 消除了嵌入的需要。 我更新了模型。您正在编写有关多对多关联的内容,但如果您引入代理 id,这不是多对多关联。除此之外,您不需要将这种特殊情况建模为多对多,而且通常不需要多对多关联。不过,我发布的模型应该适用于您的情况。 谢谢。最终,我想看看是否有可能拥有CarClassType 实体。我可以从CarClassType 表中删除id 列。正如您所指出的,这不是必需的。但是我认为为了定义CarClassTypeSale实体和Car&ClassType这两个实体之间的关系,必须要有一个CarClassType实体,你同意吗? 你可以用任何你喜欢的方式对其建模,但是你应该如何建模它应该由需求驱动,因为这会在语义上产生差异。我不知道你的实际要求,但在这个特定的例子中,我会放弃CarClassType

以上是关于JPA - 一个实体如何引用多对多关系中涉及的两个其他实体?的主要内容,如果未能解决你的问题,请参考以下文章

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

Spring,JPA:如何使用多对多关系桥表设置查询另一个实体下的实体

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

JPA的一对多,多对多用法

JPA 与存储在不同数据库中的用户实体的多对多关系

关于JPA一对一,一对多(多对一),多对多的详解