【问题标题】:I have problem with update object in many-to-many (Spring Boot)我在多对多(Spring Boot)中更新对象有问题
【发布时间】:2020-07-17 04:46:31
【问题描述】:

我有两个具有多对多关系的类(用户和成就)。当我创建并建立它们之间的关系,然后我想使用 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;
    }
}

【问题讨论】:

    标签: hibernate spring-boot many-to-many crud put


    【解决方案1】:

    你应该只在一侧设置@JoinTable,这是关系的所有者。另一端是反向端,应该只引用它所映射的另一个类中的集合,在你的情况下是@ManyToMany(mappedBy="openUserList")(其他关系也是如此)。

    根据documentation

    如果关联是双向的,一侧必须是所有者,一侧必须是反向端(即更新关联表中的关系值时将被忽略)

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2018-06-01
      • 2020-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-21
      • 1970-01-01
      • 1970-01-01
      • 2019-03-07
      相关资源
      最近更新 更多