У меня проблема с обновлением объекта во многих для многих (Spring Boot) - PullRequest
1 голос
/ 05 апреля 2020

У меня есть два класса (Пользователь и Достижение) с отношением многие ко многим. Когда я создаю и устанавливаю sh связь между ними, а затем хочу обновить любой из объектов, используя метод put, связь в таблице "user_achievement_open" удаляется. Где моя ошибка?

Целое предназначено для назначения группы задач под общим названием «Достижение». Затем пользователь может выбрать, какое достижение он будет делать. Разные пользователи могут выполнять одно и то же достижение. Один пользователь может выполнить несколько разных достижений одновременно.

@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private int userId;

    @Column(name = "username")
    private String username;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "user_data_id")
    private UserData userDataId;

    @OneToMany(mappedBy = "userId")
    private List<Realization> realizationList;

    @ManyToMany
    @JoinTable(
            name = "user_achievement_open",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "achievement_id"))
    private List<Achievement> openAchList;

    @ManyToMany
    @JoinTable(
            name = "user_achievement_finished",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "achievement_id"))
    private List<Achievement> finishedAchList;

    public User() {
    }

    public User (String username) {

        this.username = username;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int id) {
        this.userId = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public UserData getUserDataId() {
        return userDataId;
    }

    public void setUserDataId(UserData userData) {
        this.userDataId = userData;
    }

    public void addData(UserData tempUserData) {

        if (userDataId != null) userDataId = null;
        this.userDataId = tempUserData;
    }

    public List<Realization> getRealizationList() {
        return realizationList;
    }

    public void setRealizationList(List<Realization> realizationList) {
        this.realizationList = realizationList;
    }

    public void addRealization(Realization theRealization) {

        if(realizationList == null) realizationList = new ArrayList<>();
        realizationList.add(theRealization);
        theRealization.setUserId(this);
    }

    public List<Achievement> getOpenAchList() {
        return openAchList;
    }

    public void setOpenAchList(List<Achievement> achievementList) {
        this.openAchList = achievementList;
    }

    public void addOpenAch(Achievement theAchievement) {

        if(openAchList == null) openAchList = new ArrayList<>();
        openAchList.add(theAchievement);
    }

    public void removeOpenAch(Achievement theAchievement) {

        if(openAchList.contains(theAchievement)) openAchList.removeIf(Objects::nonNull);
    }

    public List<Achievement> getFinishedAchList() {
        return finishedAchList;
    }

    public void setFinishedAchList(List<Achievement> finishedAchList) {
        this.finishedAchList = finishedAchList;
    }

    public void addFinishedAch(Achievement theAchievement) {

        if(finishedAchList == null) finishedAchList = new ArrayList<>();
        finishedAchList.add(theAchievement);
    }

    public void removeFinishedAch(Achievement theAchievement) {

        if(finishedAchList.contains(theAchievement)) finishedAchList.remove(theAchievement);
    }
}


@Entity
@Table(name = "achievement")
public class Achievement {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "achievement_id")
    private int achievementId;

    @Column(name = "title")
    private String title;

    @OneToMany(mappedBy = "achievementId",
                cascade = CascadeType.ALL)
    private List<Quest> questList;

    @JsonIgnore
    @ManyToMany
    @JoinTable(
            name = "user_achievement_open",
            joinColumns = @JoinColumn(name = "achievement_id"),
            inverseJoinColumns = @JoinColumn(name = "user_id"))
    private List<User> openUserList;

    @ManyToMany
    @JoinTable(
            name = "user_achievement_finished",
            joinColumns = @JoinColumn(name = "achievement_id"),
            inverseJoinColumns = @JoinColumn(name = "user_id"))
    private List<User> finishedUserList;

    public Achievement() {
    }

    public Achievement(String title) {
        this.title = title;
    }

    public int getAchievementId() {
        return achievementId;
    }

    public void setAchievementId(int achievementId) {
        this.achievementId = achievementId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public List<Quest> getQuestList() {
        return questList;
    }

    public void setQuestList(List<Quest> questList) {
        this.questList = questList;
    }

    public void addQuest(Quest theQuest) {

        if(questList == null) questList = new ArrayList<>();
        questList.add(theQuest);
        theQuest.setAchievementId(this);
    }

    public List<User> getOpenUserList() {
        return openUserList;
    }

    public void setOpenUserList(List<User> userList) {
        this.openUserList = userList;
    }
}

1 Ответ

0 голосов
/ 05 апреля 2020

Вы должны установить @JoinTable только с одной стороны, которая является владельцем отношений. Другая сторона является обратным концом и должна ссылаться только на коллекцию в другом классе, которому она сопоставлена, что в вашем случае будет @ManyToMany(mappedBy="openUserList") (и то же самое для других отношений).

Согласно документации :

Если связь двунаправленная, одна сторона должна быть владельцем, а другая - обратной стороной (ie. Будет игнорироваться при обновлении значений отношений в таблице ассоциаций)

Надеюсь, это поможет.

...