Как удалить детей-сирот при сохранении родителя

Вкратце ситуация следующая

У меня есть документ, в документе много полей разных типов. Одно из этих полей имеет тип авторизации, который принимает список действий авторизатора. Мне нужно, чтобы при обновлении документа и изменении списка действий авторизатора старые действия авторизатора успешно удалялись из БД.

      class Document {
    @OneToMany(mappedBy = "_field", fetch = FetchType.LAZY, cascade = {
            CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE, CascadeType.DETACH})
    private final SortedSet<Field<?>> _fields = new TreeSet<>();
}

class Field<T> {
    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "document_id", nullable = false)
    private Document _document;

    @OneToMany(mappedBy = "_documentField", fetch = FetchType.LAZY, cascade = CascadeType.ALL,
           orphanRemoval=true )
    private SortedSet<AuthorizerAction> _authorizers;
}

class AuthorizerAction {
   @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.REFRESH } )
   @JoinColumn(name = "field_id", nullable = false)
   private Field<FiledAuthType> _documentField;

   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "user_id")
   private User _authorizer;
}

Но какие бы изменения я ни применял, у меня возникают разные проблемы, или они просто не работают должным образом, и я не могу найти элегантное решение без ручного удаления авторизаторов из БД.

Предположим, я получаю объект Document из БД со всеми его зависимостями. Я меняю список AuthorizerActions, и когда я сохраняю объект документа, я использую

_documentDao.save(document);

После сохранения запускается удаление сирот, но происходит сбой с ошибкой, что объект уже отсоединен.

  • В некоторых случаях потерянные элементы успешно удаляются, в основном при обновлении объекта AuthorizerActions.
  • В других случаях ошибка не выдается, но потерянные файлы не удаляются из БД, и
  • В некоторых случаях выдается такая ошибка.
      Caused by: java.lang.IllegalArgumentException: Removing a detached instance com.test.document.domain.AuthorizerAction#6
at org.hibernate.jpa.event.internal.core.JpaDeleteEventListener.performDetachedEntityDeletionCheck(JpaDeleteEventListener.java:52)
at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:89)
at org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:1013)
at org.hibernate.internal.SessionImpl.delete(SessionImpl.java:943)
at org.hibernate.engine.internal.Cascade.deleteOrphans(Cascade.java:553)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:526)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:423)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:386)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:193)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:126)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:445)
at org.hibernate.event.internal.DefaultPersistEventListener.justCascade(DefaultPersistEventListener.java:172)

Не могли бы вы помочь мне понять, где я ошибаюсь?

0 ответов

Другие вопросы по тегам