java - 如何自动删除连接表中的行以避免 ConstraintViolationException?

标签 java hibernate orm jpa jpql

这似乎应该是一个非常简单的问题,或者至少有一个简单的答案。但是 - 我真的不是数据库专家,而且我在 Hibernate 学习曲线上还差得很远。也就是说,这是设置:

考虑两个实体之间的单向多对多关系,从 FooBar:

(请原谅下面的任何错别字,以下显然是对实际代码的简化)

FooDTO.java:

@Entity
@Table(name = "MyDB.dbo.Foo")
class FooDTO implements Serializable
{
    private int id;
    private String name;
    private Set<BarDTO> bars = new HashSet<BarDTO>();

    ...

    @Fetch(FetchMode.JOIN)
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "MyDB.dbo.FooBar",
               joinColumns = { @JoinColumn(name = "fooId") },
               inverseJoinColumns = { @JoinColumn(name = "barId") })
    public Set<BarDTO> getBars()
    {
        return bars;
    }
    public void setBars(Set<Bar> bars)
    {
        this.bars = bars;
    }
}

BarDTO.java:

@Entity
@Table(name = "MyDB.dbo.Bar")
class BarDTO implements Serializable
{
    private int id;
    private String name;

    ...
}

在TSQL端,连接表是这样设置的:

CREATE TABLE [dbo].[FooBar](
    [id] [int] NOT NULL IDENTITY PRIMARY KEY,
    [fooId] [int] NOT NULL,
    [barId] [int] NOT NULL,
    CONSTRAINT fk_FooBar_FooId FOREIGN KEY (fooId) REFERENCES [dbo].[Foo](id),
    CONSTRAINT fk_FooBar_BarId FOREIGN KEY (barId) REFERENCES [dbo].[Bar](id),
) ON [PRIMARY]
END

如果我尝试彻底删除 BarDTO,我会得到一个 ConstraintViolationException,因为我没有先删除连接表中的行(duh)。

问题:

  • 当我删除 Bar 时,我能否让 Hibernate 自动删除连接表中的行?怎么样?
  • 如果没有,我如何选择所有具有特定 BarFoo,以便我可以从每个相关的 Bar 中删除该 Bar FooBar 集?

关于后一个问题,我认为这可以通过 NamedQuery 或使用 Criteria API 来完成,但我不知 Prop 体如何编写这样的查询或应用哪些约束。我认为命名查询看起来像这样:

SELECT f FROM FooDTO f INNER JOIN ??? WHERE f.id = ???

但我不确定 barId 参数会去哪里,或者如何加入 FooBar 表,因为我没有将它声明为实体。 (旁注,我还记得以前尝试加入命名查询的问题 - 加入命名查询是不可能的吗?)

最佳答案

Can I get Hibernate to drop the rows in the join table automagically, when I delete a Bar? How?

您需要从 FooDTO 中的集合中删除 BarDTO 实例,该实例持有对它的引用。

If not, how do I select all the Foos that have a particular Bar, so I can remove that Bar from each relevant Foo's set of Bars?

以下应该有效:

SELECT f FROM FooDTO f WHERE :bar MEMBER OF f.bars 

或者您可以建立双向关联,只需调用 bar.getFoos()

关于java - 如何自动删除连接表中的行以避免 ConstraintViolationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3719814/

相关文章:

Java:使用 Stream API 从原始数组创建列表

javascript - Sequelize 播种机找不到模型的正确列名称

javascript - sequelize.js 自定义验证器,检查唯一的用户名/密码

java - 在 PersonaC30 证卡打印机上进行 Jpanel 打印

Java泛型的声明有点复杂?

mysql - hibernate - 两个日期之间的差异

hibernate - 覆盖 OneToMany 关联中的延迟获取

mysql - Hibernate 不产生级联

java - 线程中的异常 "main"java.lang.IllegalStateException : Cannot get a text value from a numeric cell

java - Hibernate:实体内部类没有默认构造函数