如何自动删除连接表中的行,以避免出现ConstraintViolationException?

时间:2010-09-15 16:41:40

标签: 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自动删除连接表中的行?怎么样?
  • 如果没有,我如何选择具有特定Foo的所有Bar,这样我就可以从每个相关Bar的{​​{1}}组中删除Foo Bar S'

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

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

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

1 个答案:

答案 0 :(得分:2)

  

当我删除一个Bar时,我可以让Hibernate自动删除连接表中的行吗?怎么样?

您需要从包含引用的BarDTO中的集合中删除FooDTO实例。

  

如果没有,我如何选择所有具有特定条形图的Foo,这样我就可以从每个相关Foo的条形图块中删除该条形图?

以下内容应该有效:

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

或者您可以将关联设为双向,只需拨打bar.getFoos()