Похоже, это должен быть довольно простой вопрос или, по крайней мере, простой ответ.Но - я на самом деле не парень в базе данных, и я все еще довольно далеко на кривой обучения Hibernate.Тем не менее, вот установка:
Рассмотрим однонаправленное отношение многих ко многим между двумя сущностями, от Foo
до Bar
:
(извините за любые опечатки ниже,следующее, очевидно, является упрощением фактического кода)
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
, потому что я не удалил строку в таблице объединения в первый раз (Дух).
Вопросы:
- Можно ли заставить Hibernate автоматически удалять строки в объединяемой таблице при удалении
Bar
?Как? - Если нет, как мне выбрать все
Foo
с определенным Bar
, чтобы я мог удалить это Bar
из каждого соответствующего Foo
набора Bar
s?
Что касается последнего вопроса, я думаю это может быть сделано либо с NamedQuery
, либо с использованием Criteria API, но я не знаю, как конкретнонаписать такой запрос или какие ограничения применять.Я думаю, что именованный запрос будет выглядеть примерно так:
SELECT f FROM FooDTO f INNER JOIN ??? WHERE f.id = ???
, но я не уверен, куда пойдет параметр barId
или как присоединиться к таблице FooBar
, так как я необъявить его как сущность.(Примечание: я также вспоминаю предыдущие проблемы с попыткой объединения в именованном запросе - возможно ли объединение в именованном запросе?)