我正在尝试使用JPA生成许多Team
,每个由多个Person
对象组成。我知道我需要手动更新多对多关系的两端,所以这就是我要做的。
这里是Person.java
(为简洁起见,省略了getter和setter)。
/**
* Represents any person (teaching assistant, student, or other) that exists in this application.
*/
@Entity
@Table(name = "people")
@Inheritance(
strategy = InheritanceType.JOINED
)
public abstract class Person extends BasicEntity {
@Column(nullable = false)
private String firstName;
@Column(nullable = false)
private String lastName;
@Column
private String emailAddress;
/**
* The list of teams that this person belongs to.
*/
@ManyToMany(
cascade = CascadeType.ALL,
fetch = FetchType.LAZY
)
@JoinTable(
name = "team_members",
joinColumns = @JoinColumn(name = "person_id"),
inverseJoinColumns = @JoinColumn(name = "team_id")
)
private List<Team> teams;
/**
* Default constructor for JPA.
*/
protected Person () {
this.teams = new ArrayList<>();
}
/**
* Constructs a new Person.
* @param firstName The person's first name.
* @param lastName The person's last name.
* @param emailAddress The person's email address.
*/
public Person(String firstName, String lastName, String emailAddress) {
this();
this.firstName = firstName;
this.lastName = lastName;
this.emailAddress = emailAddress;
}
public void assignToTeam(Team team) {
this.teams.add(team);
//team.addMember(this);
}
如您所见,在assignToTeam
方法中,我注释了“自反”部分,在更新{{1}之后,我在其中更新了关系的Team
表示形式}。
由于有必要解决此问题,因此这里为Person
。
Team.java
当我为我的应用程序生成一组测试数据时,会发生问题,并且我调用以下方法:
/**
* A group consisting of one or more members. Child classes should define P as a sub class of Person to define custom
* behavior if needed.
* @param <P> The type of members this group contains.
*/
@Entity
@Inheritance(
strategy = InheritanceType.JOINED
)
public abstract class Team<P extends Person> extends BasicEntity {
/**
* The list of members in this group.
*/
@ManyToMany(
cascade = CascadeType.ALL
)
@JoinTable(
name = "team_members",
joinColumns = @JoinColumn(name = "team_id"),
inverseJoinColumns = @JoinColumn(name = "person_id")
)
protected List<P> members;
/**
* The course that this team belongs to.
*/
@ManyToOne(
optional = false
)
private Course course;
/**
* Default constructor for JPA and initializing list of members for any child classes.
*/
protected Team() {
this.members = new ArrayList<>();
}
public void addMember(P person) {
if (!this.containsMember(person)) {
this.members.add(person);
}
}
会导致以下性质的错误:
private List<StudentTeam> generateStudentTeams() {
StudentGenerator studentGenerator = new StudentGenerator(this.getSeed());
List<StudentTeam> teams = new ArrayList<>(this.studentGroupCount);
for (int i = 0; i < this.studentGroupCount; i++) {
StudentTeam team = new StudentTeam();
List<Student> students = studentGenerator.generateList(this.studentGroupSize);
for (Student s : students) {
s.assignToTeam(team);
}
teams.add(team);
}
return teams;
}
我的问题是,如何正确设置关系的双方并避免出现此类问题?
答案 0 :(得分:0)
如果您选择双向映射关系,则一个 方向必须定义为所有者,另一个必须使用 mappedBy 属性来定义其映射。这也避免了必须 在两个地方都复制 JoinTable 信息。
如果未使用mappedBy,则持久性提供程序将假定 有两个独立的关系,您最终会得到 重复的行插入到联接表中。如果你有一个概念 双向关系,但在 数据库,那么您一定不能使用mapledBy,因为您需要维护 两个独立的表。
https://en.wikibooks.org/wiki/Java_Persistence/ManyToMany#Bi-directional_Many_to_Many