JPA OneToMany не удаляет ребенка

Итак, вот как это должно работать в соответствии со спецификацией (во время компиляции и при условии правильной навигации по документам):

Компилятор идентифицирует список методы сопоставления из типа D и его базовых типов, основанные на имени метода и списке аргументов. Это означает, что любой метод с именем Foo, принимающий один параметр типа, для которого существует неявное преобразование из B, является допустимым кандидатом. Это приведет к следующему списку:

C.Foo(B) (public virtual)
D.Foo(B) (public override)
D.Foo(A) (public)

Из этого списка исключаются любые объявления, содержащие модификатор переопределения. Это означает, что список теперь содержит следующие методы:

C.Foo(B) (public virtual)
D.Foo(A) (public)

. В этот момент у нас есть список подходящих кандидатов, и теперь компилятор должен решить, что вызывать. В документе 7.5.5.1 Вызов метода мы находим следующий текст:

Если N применимо относительно A (). Раздел 7.4.2.1 ), то все методы, объявленные в базовом типе T, удаляются из набора.

blockquote>

Это по существу означает, что если есть применимый метод, объявленный в D, любые методы из базовые классы будут удалены из списка. На этом этапе у нас есть победитель:

D.Foo(A) (public)

146
задан g00glen00b 22 February 2018 в 13:12
поделиться

4 ответа

[

] поведение JPA корректно (имеется в виду [] в соответствии со спецификацией []): объекты не удаляются просто потому, что вы удалили их из коллекции OneToMany. Существуют расширения, специфичные для конкретного производителя, но встроенные в JPA, они не подходят.[

] [

]Частично это происходит потому, что JPA на самом деле не знает, следует ли удалять что-то, удаленное из коллекции. В терминах объектного моделирования это разница между []составом [] и "агрегированием*. [

] [

] В []составе [] дочерняя сущность не существует без родителя. Классический пример - между домом и комнатой. Удаление дома и комнаты тоже идет.[

] [

][]Агрегация[] является более слабым видом ассоциации и типизируется как "Курс", так и "Студент". Удалите Курс, и Студент все еще существует (вероятно, в других курсах).[

] [

]Так что вам нужно либо использовать расширения, специфичные для производителя, чтобы заставить это поведение (если доступно), либо явно удалить ученика и удалить его из родительской коллекции.[

] [

]Я знаю:[

] []
245
ответ дан 23 November 2019 в 22:28
поделиться
[

] В дополнение к ответу cletus, []JPA 2.0[], последний с декабря 2010 года, вводит атрибут []orphanRemoval[] в аннотации []@OneToMany[]. Для более подробной информации смотрите запись в блоге [] []. [

] [

] Обратите внимание, что поскольку спецификация относительно новая, не все провайдеры JPA 1 имеют окончательную реализацию JPA 2. Например, версия []Hibernate 3.5.0-Beta-2[] еще не поддерживает этот атрибут.[

].
69
ответ дан 23 November 2019 в 22:28
поделиться
[

] Здесь каскад, в контексте удаления, означает, что дети удаляются, если вы удаляете родителя. Не ассоциация. Если вы используете Hibernate в качестве поставщика JPA, вы можете сделать это, используя []специальный каскад в режиме гибернации[].[

].
3
ответ дан 23 November 2019 в 22:28
поделиться

Как было объяснено, с JPA невозможно делать то, что я хочу, поэтому я использовал hibernate.cascade annotation, при этом соответствующий код в классе Parent теперь выглядит следующим образом:

@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, mappedBy = "parent")
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,
            org.hibernate.annotations.CascadeType.DELETE,
            org.hibernate.annotations.CascadeType.MERGE,
            org.hibernate.annotations.CascadeType.PERSIST,
            org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
private Set<Child> childs = new HashSet<Child>();

Я не мог просто использовать 'ВСЕ', так как это удалило бы и родителя.

19
ответ дан 23 November 2019 в 22:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: