Имам обект A
, който има колекция от основни типове (напр. String
). Използвам такова съпоставяне, защото низовете, свързани с всеки екземпляр на A
, зависят от жизнения цикъл на A
. Ако искам да премахна екземпляр на A
от DB, искам също да премахна свързаните с него String
s.
Моето картографиране е както следва:
@Entity
public class A {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "name", nullable = false, unique = true)
private String name;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "AStrings", joinColumns = @JoinColumn(name = "id"))
@Column(name = "strings", nullable = false)
private Set<String> strings;
}
Ако създам екземпляр на A
и му добавя някои низове, тогава мога да запазя екземпляра с помощта на Session.save(myInstance)
. Както екземплярът на A
, така и свързаните с него String
s се запазват.
Но ако искам да премахна същия екземпляр от DB, използвайки Session.createQuery("delete A a where a.name = ?").setString(0, name).executeUpdate()
, получавам грешка при ограничение на външен ключ:
Не може да се изтрие или актуализира родителски ред: ограничение за външен ключ е неуспешно
Но бих очаквал свързаните String
s да бъдат премахнати автоматично, преди да премахнете екземпляра на A
, но изглежда, че не е така. Също така не намерих начин да задам каскадни правила.
Има ли нещо нередно с конфигурацията ми?
Благодаря
РЕДАКТИРАНЕ: Опитах също да използвам @Cascade(CascadeType.DELETE)
на поле strings
и пак не помага. Разглеждайки базата данни, не виждам никаква ON DELETE
политика за съответния външен ключ.
Някой, който е имал същия проблем, отвори JIRA: https://hibernate.onjira.com/browse/HHH-4301. Трябва да съществува решение (или заобиколно решение), не мога да бъда единственият човек, който използва @ElementCollection
.
Реших проблема. Мислех, че изтриването чрез Session.delete() или използването на HQL заявка е еквивалентно, но изглежда не е така. Използвайки HQL заявка, зависимите обекти не се изтриват автоматично, така че получавам грешка при ограничение на външен ключ. Използването на Session.delete() решава проблема. Освен това изглежда, че Hibernate не използва каскадна функционалност на DB, тъй като все още не виждам никаква CASCADE политика в генерирания DDL, той обработва това вътрешно.