playframework的多对多删除问题

Posted

技术标签:

【中文标题】playframework的多对多删除问题【英文标题】:many-to-many deleting problem with playframework 【发布时间】:2011-03-23 15:33:17 【问题描述】:

PlayFramework(JPA、休眠)。两个实体softwaretagsoftware 是关系的所有者。而且我不使用任何cascading。 我想删除一个tag,里面有一些软件。

考虑到software 是所有者,我在我的标签类中写:

class Tag 
  @Override
  public Tag delete() 
    for (Software software : this.softwares) 
        software.tags.remove(this);
        software.save(); // if we delete this, we will have an error - a foreign key constraint fails
    
    return super.delete();
  

在我添加了software.save() 行之后,它现在运行良好。 问题是:我为什么要这样做?

我有另一个项目 - 没有 Play Framework - 它使用 JPA->Hibernate,我不必这样做。那么有什么区别呢?

在this link 中,他们也不使用 save()。

【问题讨论】:

【参考方案1】:

您链接到的示例中的代码与您的代码不完全相同。

在您链接的代码中,他们正在删除一些元素,但如果您在下面的评论中阅读,他们会说:

// then merge() and flush()

这会将更改保存到数据库中。他们也正在从拥有该关系的类中删除。

在您的场景中,您正在删除标签,而所有者是关系的另一端。所以你(正确地)使用 software.tags.remove 来清理关系。

现在,如果您不保存,实体管理器尚未确认更改,当它尝试删除标记时,该实体管理器检测到 M:N 活动关系并失败。

原因是 Play 的 explicit save,您必须告诉系统要保存的更改,这与 Hibernate (JPA) 工作的“默认”方式不同,其中对象自动提交(随着更改)交易何时结束。

【讨论】:

实际上即使使用 Tag.em().persist() 也需要使用 save(),是不是意味着 play 对 EnityManager/Hibernate 有影响? IE。这个 em() 已经准备好/配置为需要明确使用 save() 吗? 是的,如果您阅读了我在上面发布的链接,您需要明确地说“保存”以存储更改。

以上是关于playframework的多对多删除问题的主要内容,如果未能解决你的问题,请参考以下文章

PlayFramework中模型之间的“双重”多对多关系

删除 NSManagedObject 子类不会取消它的多对多关系

Prisma 删除与复合键的多对多关系

如何从 SqlAlchemy 中的多对多集合中删除所有项目?

当对集合进行 get 调用时,Hibernate 会删除延迟加载的多对多集合

如何删除与隐藏交集表的多对多关联中的记录?