Невозможно удалить объект, который является целью отношения @OneToOne - PullRequest
4 голосов
/ 20 января 2011

У меня есть следующие объекты с отношением @OneToOne:

@Entity
public static class EntityChild extends BaseEntity {
    //Id from superclass
}

@Entity
public static class EntityParent extends BaseEntity {

    //Id from superclass

    @OneToOne(cascade = ALL)
    private EntityChild child;

    //child getter/setter
}

Теперь следующий тест не пройден:

EntityParent parent = new EntityParent();
em.persist(parent);
em.flush();

EntityChild child = new EntityChild();
parent.setChild(child);
em.persist(parent);
em.flush();

em.remove(parent.getChild());
em.flush();

Выдает исключение в последней строке с помощью flush (). Исключение составляет javax.persistence.EntityNotFoundException: deleted entity passed to persist: [my.package.EntityChild#<null>]

Почему я не могу удалить эту сущность?

1 Ответ

5 голосов
/ 20 января 2011

Сначала необходимо удалить связь между родителем и ребенком, в противном случае Hibernate попытается снова сохранить ребенка из-за cascade = ALL:

EntityChild c = parent.getChild();
parent.setChild(null);
em.remove(c);
em.flush(); 

Обновление:

Вот выдержки из спецификации JPA , относящиеся к этому поведению. Исключение выдается из-за конфликта между [1] и [2] во время flush() (хотя я не могу найти, где это указано):

Семантика операции flush , применяемой к сущности X, выглядит следующим образом:

  • Если X является управляемым объектом, он синхронизируется с базой данных.

    • Для всех объектов Y, на которые ссылается отношение из X, если отношение к Y было аннотированный значением элемента cascade cascade=PERSIST или cascade=ALL, операция сохранения применяется к Y.

    • Для любого объекта Y, на который ссылается отношение из X, где отношение к Y имеет не был аннотирован значением элемента cascade cascade=PERSIST или cascade= ALL:

      • Если Y новый или удален, будет выброшено IllegalStateException с помощью операции сброса (и транзакции, помеченной для отката) или транзакции фиксация завершится неудачей.

      • Если Y отделен, семантика зависит от принадлежности отношений. Если X принадлежит отношение, любые изменения отношения синхронизируются с базой данных; в противном случае, если Y владеет отношениями, поведение не определено.

  • Если X является удаленным объектом, он удаляется из базы данных. Никакие каскадные опции не актуальны. <--------------- [1] </strong>


Семантика persist операция, примененная к сущности X следующим образом:

  • Если X новый объект, он становится управляемым. Объект X будет введены в базу данных в или до фиксация транзакции или в результате операция промывки.

  • Если X является существующий управляемый объект, это игнорируется сохраняющейся операцией. Тем не менее, постоянная операция каскадно к сущностям, на которые ссылается X, если отношения от X к этим другие лица помечены с cascade=PERSIST или cascade=ALL значение элемента аннотации или указанное с эквивалентным дескриптором XML элемент.

  • Если X является удаленным объектом, это становится управляемым. <--------------- [2] </strong>

  • Если X является обособленный объект, EntityExistsException может быть брошено когда вызывается постоянная операция, или EntityExistsException или другой PersistenceException может быть бросается на флеше или во время коммита.

  • Для все объекты Y, на которые ссылается Отношение от Х, если отношение к Y было аннотировано со значением каскадного элемента cascade=PERSIST или cascade=ALL, постоянная операция применяется к Y.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...