[英]How do I delete a row in a join table automatically, to avoid a ConstraintViolationException?
This seems like it should be a pretty simple question, or at least have a simple answer. 这似乎应该是一个非常简单的问题,或者至少有一个简单的答案。 But - I'm really not a database guy, and I'm still pretty far down on the Hibernate learning curve.
但是 - 我真的不是一个数据库人,而且我在Hibernate学习曲线上的表现还很不错。 That said, here's the setup:
也就是说,这是设置:
Consider a unidirectional many-to-many relationship between two entities, from Foo
to Bar
: 考虑两个实体之间的单向多对多关系,从
Foo
到Bar
:
(pardon any typos below, the following is obviously a simplification of the actual code) (请原谅以下任何拼写错误,以下显然是对实际代码的简化)
@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;
}
}
@Entity
@Table(name = "MyDB.dbo.Bar")
class BarDTO implements Serializable
{
private int id;
private String name;
...
}
On the TSQL side, the join table is set up like this: 在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
If I try to outright delete a BarDTO
, I get a ConstraintViolationException
because I haven't first deleted the row in the join table (duh). 如果我试图直接删除
BarDTO
,我会得到一个ConstraintViolationException
因为我没有先删除连接表中的行(duh)。
Bar
? Bar
时,我可以让Hibernate自动删除连接表中的行吗? How? Foo
s that have a particular Bar
, so I can remove that Bar
from each relevant Foo
's set of Bar
s? Bar
所有Foo
,所以我可以从每个相关Foo
的Bar
s中删除该Bar
? With regard to the latter question, I think this could be done with either a NamedQuery
or using the Criteria API, but I don't know specifically how to write such a query or which constraints to apply. 关于后一个问题,我认为可以使用
NamedQuery
或使用Criteria API来完成,但我不知道如何编写这样的查询或应用哪些约束。 I think it would a named query would look something like: 我认为命名查询看起来像是这样的:
SELECT f FROM FooDTO f INNER JOIN ??? WHERE f.id = ???
but I'm not sure where the barId
parameter would go, or how to join on the FooBar
table since I don't declare it as an entity. 但是我不确定
barId
参数会去哪里,或者如何加入FooBar
表,因为我没有将它声明为实体。 (Side note, I also recall previous issues with trying to join in a named query - is joining in a named query impossible?) (旁注,我还记得以前尝试加入命名查询的问题 - 加入命名查询是不可能的?)
Can I get Hibernate to drop the rows in the join table automagically, when I delete a Bar?
当我删除一个Bar时,我可以让Hibernate自动删除连接表中的行吗? How?
怎么样?
You need to remove the BarDTO
instance from the collections in FooDTO
that holds a reference on it. 您需要从
FooDTO
中的集合中删除BarDTO
实例,该集合中FooDTO
的引用。
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?
如果没有,我如何选择所有具有特定条形的Foo,这样我就可以从每个相关Foo的条形图中删除该条形图?
The following should work: 以下应该有效:
SELECT f FROM FooDTO f WHERE :bar MEMBER OF f.bars
Or you could make the association bidirectional and simply call bar.getFoos()
. 或者你可以使关联双向,只需调用
bar.getFoos()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.