【问题标题】:Bidirectional @ManyToMany doesn't remove records from the join table xx_yy with CascadeType.ALL双向 @ManyToMany 不会使用 CascadeType.ALL 从连接表 xx_yy 中删除记录
【发布时间】:2017-02-24 04:46:09
【问题描述】:

我正在实施分类系统,其中一个类别通常有多个子类别,一个子类别至少有一个父类别,但肯定会有子类别有多个父类别的情况。

这就是我选择ManyToMany方法的原因。

所以,Category

public class Category implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "cat_id", nullable = false)
    private Integer catId;
    ....    
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(
        name = "cats_subcats",
        joinColumns = @JoinColumn(name = "cat_id"),
        inverseJoinColumns = @JoinColumn(name = "subcat_id")
    )
    private Set<Subcategory> subcats;
    ....

Subcategory:

public class SubCategory implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "subcat_id", nullable = false)
    private Integer subcatId;
    ....
    @ManyToMany(cascade = CascadeType.ALL, mappedBy = "subcats")
    private Set<Category> cats;
    ....

此设置有效,它创建连接表,插入我的两个虚拟子目录,并在连接表中创建两个连接记录。

然后我继续测试它在不同场景下的表现。

首先,我想从包含三个子类别的现有类别中删除一个子类别。

我的托管 bean:

....
@PostConstruct
    public void init() {

    category = new Category();
    category.setName("Programmatically added ctg");
    category.setSlug("programmatically-added-crg");

    Set<Subcategory> subcats = new HashSet<>(2);

    Subcategory subcat = new Subcategory();
    subcat.setName("Subcat one");
    subcats.add(subcat);

    Subcategory subcat2 = new Subcategory();
    subcat2.setName("Subcat to be removed");
    subcats.add(subcat2);

    Subcategory subcat3 = new Subcategory();
    subcat3.setName("The most recent subcat");
    subcats.add(subcat3);

    category.setSubcats(subcats);

    // this initially saves both the cat and the subcats
    ctgService.save(category);
    categories = ctgService.getAll();

    // now I remove one of the three subcats
    category.getSubcats().remove(subcat2);

    // this is a method belonging to my service (EJB)
    ctgService.update(category);

    // upon re-fetching, I can see in my DB that the subcat has not been removed
    categories = ctgService.getAll();
}
....

我通过将(在Category 实体中)@ManyToMany(cascade = CascadeType.ALL) 更改为 @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) 来使其工作。

确实,它会根据需要删除子猫,但是...当我查看我的类别时(在这种情况下只有一个)-我可以看到它以某种方式已被重新插入,因为它现在具有 @987654330 @ 的 2 而不是 1

谁能解释一下我遇到的任何/两个问题?

【问题讨论】:

  • 我有第一个。似乎是一个错误。关于第二个,我认为您还必须执行 subcat2.getCats().remove(category) ?因为它是双向的

标签: java hibernate many-to-many entity jpa-2.1


【解决方案1】:

我认为你想要“orpahnremoval”,但它在 @ManyToMany 上不可用

How do I delete orphan entities using hibernate and JPA on a many-to-many relationship?

【讨论】:

  • 我已经知道orphanRemoval = true(无论如何谢谢),但正如你所指出的,很遗憾这里不可用。但是,正如我在问题接近尾声时所说,如果我将 CascadeType.ALL 更改为某些单独的级联类型,它会按预期工作,但由于某种原因,我的类别的 id 增加了 1(就像它首先被删除一样,然后重新创建但没有将自动增量值重置回 1。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 2011-06-01
  • 2015-08-05
  • 1970-01-01
  • 2022-01-13
  • 2012-01-30
  • 1970-01-01
相关资源
最近更新 更多