spring-boot - Spring Boot(JPA)中的多个@JoinTable
问题描述
我有以下代码(Spring Boot)可以完美运行:
@Getter
@Setter
@ManyToMany(fetch = FetchType.LAZY)
@Column(name = "fight")
@JoinTable(name = "fighter_fight",
joinColumns = {@JoinColumn(name = "fighter_id")},
inverseJoinColumns = {@JoinColumn(name = "fight_id")})
private Set<Fight> fights;
它正在创建这个表:
我需要有三列。让我们说两个fighter_id
叫做 first_fighter_id
andsecond_fighter_id
和fight_id
。当我尝试再添加一行时
joinColumns = {@JoinColumn(name = "fighter_id")},
我收到一个错误(“重复的属性 joinColumns”)。如何在一个表中有两列具有相同的对象(Fighter
在我的情况下)?
解决方案
首先,您应该考虑您是否在描述正确的模式。如果您只有 fighter1 和 fighter2 那么您可能正在谈论两个ManyToOne
这样的关系:
这应该很容易建模。如果您认为您实际上有ManyToMany
关系,可能是 WWE 之类的,并且您希望关系中有一个附加属性,那么您需要一个具有属性的关系,如下所示:
这不是一个不常见的模式要求,并且通过与ManyToOne
新实体的两个关系来实现,如下所示:
为此,简单的 JPA 实体需要像这样Embeddable
使用实体EmbeddableId
:
@Entity
@Data
public class Fight {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
@Entity
@Data
public class Fighter {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
@Entity
@Data
public class Fights {
@EmbeddedId
private FightsPK id;
@MapsId("fighterId")
@ManyToOne
private Fighter fighter;
@MapsId("fightId")
@ManyToOne
private Fight fight;
private String fId;
}
@Embeddable
@Data
public class FightsPK implements Serializable {
private static final long serialVersionUID = 1L;
private Long fighterId;
private Long fightId;
}
使用它会有点尴尬,但可行:
private void create() {
Fighter f1 = new Fighter();
fighterRepo.save(f1);
Fighter f2 = new Fighter();
fighterRepo.save(f2);
Fight f = new Fight();
fightRepo.save(f);
Fights f1s = new Fights();
f1s.setId(new FightsPK());
f1s.setFighter(f1);
f1s.setFight(f);
f1s.setFId("f1");
fightsRepo.save(f1s);
Fights f2s = new Fights();
f2s.setId(new FightsPK());
f2s.setFighter(f2);
f2s.setFight(f);
f2s.setFId("f2");
fightsRepo.save(f2s);
}
该fId
字段是一个字符串,因此您可以在其中放置任何内容,例如,如果战斗组织者需要在该字段中输入他们自己的名称。您可能需要重新考虑是否需要最初描述的关系。只有两个战斗机,您可以在Fight
fighter1 和 fighter1 名称中添加额外的字段。
推荐阅读
- c# - Visual Studio 安装项目创建的 MSI 无法从安装位置运行 exe
- reactjs - 解决 REST 请求后如何重定向用户
- mysql - Percona xtrabackup 几乎从不产生可行的备份 - 但报告“完成正常!”
- c# - 在 Azure 构建期间,想要获取 azure 管道生成的修订号以更新我的项目的 FileVersion
- node.js - 更新 JSON 数组特定字符串
- javascript - 数组有 10 个代表球员的对象,我试图在 Vue.js 中循环显示来自第 1 队的 5 名球员。我做对了吗?
- python - Django ORM:注释中的计数与查询集的计数有何不同?
- vue.js - Vue组件收到数据后如何更新
- c++ - C++ 在后台运行程序 Windows 10
- css - 使用“背景过滤器”和“填充或边框半径”无法正常工作