[英]JPA annotation for parent composite key to be part of child composite primary key
I am trying to map a race day that has multiple races, and can't figure out the annotations.我试图绘制一个有多个比赛的比赛日,但无法弄清楚注释。
What I want to end up with is something like (this is a simplified example):我想最终得到的是这样的(这是一个简化的例子):
TABLE: race_day
date (PK)
venue (PK)
description
TABLE: race
date (PK but also FK on race_day table)
venue (PK but also FK on race_day table)
race_number (PK)
description
So far I've come up with the following POJO + annotations:到目前为止,我已经提出了以下 POJO + 注释:
public class RaceDayPK implements Serializable {
@Column(name="race_date")
private String raceDate;
@Column(name="venue")
private String venue;
...
}
public class RaceDay {
@EmbeddedId
private RaceDayPK raceDayPk;
@OneToMany(mappedBy = "raceDay", orphanRemoval = true, cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
private final List<Race> races = new ArrayList<>();
...
}
public class Race {
@ManyToOne
@JoinColumns({
@JoinColumn(name = "race_date", referencedColumnName = "race_date"),
@JoinColumn(name = "venue", referencedColumnName = "venue")
})
private RaceDay raceDay;
private int raceNumber;
private String raceTitle;
...
}
How do I make an EmbeddedId for Race (I'm guessing that's what I need) with both the raceDay join column AND raceNumber in it?如何使用 RaceDay 连接列和 RaceNumber 为 Race 制作 EmbeddedId(我猜这就是我需要的)? Any help appreciated.
任何帮助表示赞赏。 I have seen dozens of JoinColumn examples and EmbeddedId examples here on StackOverflow but none that seem to combine the two in the way that I need.
我在 StackOverflow 上看到了数十个 JoinColumn 示例和 EmbeddedId 示例,但似乎没有一个以我需要的方式将两者结合起来。
After some hacking around, I think I got it working like this.经过一些黑客攻击,我想我让它像这样工作。 Note the nested "racePk.raceMeeting" in the mappedBy parameter for the OneToMany annotation:
注意 OneToMany 注释的 mappingBy 参数中嵌套的“racePk.raceMeeting”:
public class RaceDayPK implements Serializable {
@Column(name="race_date")
private String raceDate;
@Column(name="venue")
private String venue;
...
}
public class RaceDay {
@EmbeddedId
private RaceDayPK raceDayPk;
@OneToMany(mappedBy = "racePk.raceDay", orphanRemoval = true, cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
private final List<Race> races = new ArrayList<>();
...
}
public class RacePk implements Serializable {
@ManyToOne
@JoinColumns({
@JoinColumn(name = "race_date", referencedColumnName = "race_date"),
@JoinColumn(name = "venue", referencedColumnName = "venue")
})
private RaceDay raceDay;
@Column(name = "race_number")
private int raceNumber;
...
}
public class Race {
@EmbeddedId
private final RacePk racePk = new RacePk();
private String raceTitle;
...
}
No idea yet whether this will fall over at some point but the MySQL tables appear to have been auto-generated correctly.尚不知道这是否会在某个时候失败,但 MySQL 表似乎已正确自动生成。
TABLE: race_day
id(PK)
date (PK)
venue (PK)
description
TABLE: race
id(PK but also FK on race_day table)
date (PK but also FK on race_day table)
venue (PK but also FK on race_day table)
race_number (PK)
description
For the above given tables, I was able to generate the sequence and get the data persisted in the tables following the constraints using the below code.对于上面给出的表,我能够生成序列并使用以下代码将数据保留在表中的约束之后。
public class RaceDayPK implements Serializable {
private Long id;
private String raceDate;
private String venue;
...
}
@Entity
@IdClass(RaceDayPK.class)
public class RaceDay {
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator = "R_SEQ")
@SequenceGenerator(sequenceName = "RD_SEQ", allocationSize = 1, name = "R_SEQ")
private Long id;
@Id
@Column(name="race_date")
private String raceDate;
@Id
@Column(name="venue")
private String venue;
@OneToMany(mappedBy = "raceDay", cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
private Set<Race> races;
...
}
public class RacePK implements Serializable {
private RaceDay raceDay;
private int raceNumber;
...
}
@Entity
@IdClass(RacePK.class)
public class Race {
@Id
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumns({
@JoinColumn(name = "race_date", referencedColumnName = "race_date"),
@JoinColumn(name = "venue", referencedColumnName = "venue"),
@JoinColumn(name = "id", referencedColumnName = "id")
})
@JsonIgnore
private RaceDay raceDay;
@Id
private int raceNumber;
private String raceTitle;
...
}
the dao code needs to be changed a bit as to below. dao 代码需要更改如下。
public RaceDay saveRaceDay(RaceDay raceDay){
if(raceDay.getRaces()!=null){
raceDay.getRaces().forEach(race ->{
race.setRaceDay(raceDay);
});
}
}
Not sure if it works but try this approach:不确定它是否有效,但试试这个方法:
public class RacePK implements Serializable {
private RaceDayPK raceDay;
private String raceNumber;
...
}
@Entity
@IdClass(RacePK.class)
public class Race {
@Id
@ManyToOne...
private RaceDay raceDay;
@Id
private int raceNumber;
private String raceTitle;
...
}
Note that PK field names should be exactly the same as @id-annotaed field names.请注意,PK 字段名称应与@id-annotaed 字段名称完全相同。 Google for Derived identifiers to learn more.
Google for Derived identifiers 以了解更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.