Ошибка доступа к полю при обновлении сопоставления «многие ко многим» - PullRequest
0 голосов
/ 14 марта 2019

Я пытаюсь сгенерировать множество Team с, каждый из которых состоит из нескольких Person объектов, используя JPA. Я знаю, что мне нужно вручную обновить обе стороны отношения «многие ко многим», поэтому я пытаюсь это сделать.

Вот Person.java (для краткости опущены геттеры и сеттеры).

/**
 * 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 я закомментировал часть 'reflexive', в которой я обновляю представление отношения 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;
    }

, что приводит к некоторым ошибкам следующего характера: Caused by: org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistantRole nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistant.role] by reflection for persistent property [nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistant#role] : nl.andrewlalis.teaching_assistant_assistant.model.people.Student@1028bf36

У меня вопрос: как правильно установить обе стороны отношения и избежать такой проблемы?

1 Ответ

0 голосов
/ 15 марта 2019

Если вы решите отобразить отношения в обоих направлениях, то одно направление должно быть определено как владелец, а другое должно использовать атрибут mappedBy , чтобы определить его сопоставление.Это также избавляет от необходимости дублировать информацию JoinTable в обоих местах.

Если mappedBy не используется, то поставщик сохраняемости примет два независимых отношения, и вы получитеповторяющиеся строки вставляются в таблицу соединений.Если у вас есть концептуальные двунаправленные отношения, но у вас есть две разные таблицы соединений в базе данных, вы не должны использовать mappedBy, так как вам нужно поддерживать две независимые таблицы.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...