Как автоматически удалить строку в соединительной таблице, чтобы избежать исключения ConstraintViolationException? - PullRequest
3 голосов
/ 15 сентября 2010

Похоже, это должен быть довольно простой вопрос или, по крайней мере, простой ответ.Но - я на самом деле не парень в базе данных, и я все еще довольно далеко на кривой обучения 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 набора Bars?

Что касается последнего вопроса, я думаю это может быть сделано либо с NamedQuery, либо с использованием Criteria API, но я не знаю, как конкретнонаписать такой запрос или какие ограничения применять.Я думаю, что именованный запрос будет выглядеть примерно так:

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

, но я не уверен, куда пойдет параметр barId или как присоединиться к таблице FooBar, так как я необъявить его как сущность.(Примечание: я также вспоминаю предыдущие проблемы с попыткой объединения в именованном запросе - возможно ли объединение в именованном запросе?)

1 Ответ

2 голосов
/ 15 сентября 2010

Можно ли заставить Hibernate автоматически удалять строки в объединяемой таблице при удалении панели?Как?

Вам необходимо удалить экземпляр BarDTO из коллекций в FooDTO, на котором содержится ссылка.

Если нет, как выбратьвсе Foo, которые имеют определенный Бар, так что я могу удалить этот Бар из каждого соответствующего набора Баров?

Должно работать следующее:

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

Ассоциация двунаправленная и просто позвоните bar.getFoos().

...