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