更新多对多映射时访问字段时出错

时间:2019-03-14 19:38:24

标签: hibernate spring-boot jpa

我正在尝试使用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; }

我的问题是,如何正确设置关系的双方并避免出现此类问题?

1 个答案:

答案 0 :(得分:0)

  

如果您选择双向映射关系,则一个   方向必须定义为所有者,另一个必须使用    mappedBy 属性来定义其映射。这也避免了必须   在两个地方都复制 JoinTable 信息。

     

如果未使用mappedBy,则持久性提供程序将假定   有两个独立的关系,您最终会得到   重复的行插入到联接表中。如果你有一个概念   双向关系,但在   数据库,那么您一定不能使用mapledBy,因为您需要维护   两个独立的表。

https://en.wikibooks.org/wiki/Java_Persistence/ManyToMany#Bi-directional_Many_to_Many