【问题标题】:@ManyToMany with cascade = CascadeType.REMOVE removes associations AND entities@ManyToMany with cascade = CascadeType.REMOVE 删除关联和实体
【发布时间】:2015-09-02 13:25:01
【问题描述】:

我有 2 个实体:GroupGrouped,有 1 个多对多关联。

在数据库中,Association 表在 GroupGrouped 上都有一个 NOT NULL FK。

我希望 Hibernate 在删除所有分组后删除关联而不是组。

删除Grouped实体的代码:

@Autowired
private final GroupedRepository groupedRepository;

public void delete(Grouped groupedToRemove) {
    groupedRepository.delete(groupedToRemove);
}

如果我设置cascade = CascadeType.ALLcascade = CascadeType.REMOVE,当我删除Grouped 实体时,我的Group 实体将被删除,而不仅仅是关联:

@ManyToMany(cascade = CascadeType.ALL, // same behavior with CascadeType.REMOVE
        mappedBy = "grouped", 
        targetEntity = Group.class)
private Set<Group> groups = new HashSet<>();

如果我删除级联,hibernate 会尝试设置 group_id=null 并抛出 ModelConstraintException。我不想将 FK 设置为可为空。

集团实体:

@Entity
@Table(name = "groups")
@Getter
@Setter
public class Group {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @ManyToMany(targetEntity = Grouped.class)
    @JoinTable(
            name = "association",
            joinColumns = @JoinColumn(name = "group_id", nullable = false, updatable = false),
            inverseJoinColumns = @JoinColumn(name = "grouped_id", nullable = false, updatable = false)
    )
    private Set<Grouped> grouped= new HashSet<>();
}

分组实体:

@Entity
@Table(name = "grouped")
@Getter
@Setter
public class Grouped {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @ManyToMany(mappedBy = "grouped", targetEntity = Group.class)
    private Set<Group> groups= new HashSet<>();
}

【问题讨论】:

    标签: java hibernate jpa many-to-many cascade


    【解决方案1】:

    这是预期的行为。 REMOVE 级联意味着:当移除这个实体时,也移除关联的实体。这对 ManyToXxx 没有意义,因为很明显,其他实体仍在引用关联的实体。

    如果您想删除一个 Grouped,但将关联的 Groups 保留在那里,您需要先删除两个实体之间的关联:

    for (Group group : grouped.getGroups()) {
        group.getGrouped().remove(grouped);
    }
    grouped.getGroups().clear();
    

    然后删除不再与任何组关联的 Grouped 实体。

    【讨论】:

    • 发布两个实体的代码、您用于删除分组的代码以及异常的完整堆栈跟踪。
    • 是的,它有效,谢谢!所以这里重要的是:删除Grouped实体上所有Group实体的引用要删除,还要删除Grouped的所有引用要删除所有链接的Group实体上。
    • 这是我的代码示例所做的。实际上,唯一真正重要的一方是所有者方,即没有mappedBy 属性的一方。
    • 你的意思是我们可以删除 grouped.getGroups().clear(); ?
    • 是的。我把它留在那里是因为以连贯的方式修改关联的双方是一个很好的做法。
    猜你喜欢
    • 2023-03-28
    • 2010-11-09
    • 2015-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 2015-03-24
    相关资源
    最近更新 更多