Bezdepbonusu7Программирование: статьи и ответы

Вопрос

JPA CascadeType.REMOVE не работает

Автор вопроса: ArmandoОтветов: 1

У меня есть две сущности Бизнес, которые состоят из списка Отделов.

@Entity
@Table(name = "Business")
public class Business implements Serializable {

  private static final long serialVersionUID = 1L;

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "Id")
  private Long id;

  @OneToMany(mappedBy = "business",
       cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
   private List<Department> departments;

   @OneToMany(mappedBy = "business", orphanRemoval = true,
     cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
   private List<Process> processs;

   @ManyToMany
   private List<Competence> competences;
}


@Entity
@Table(name = "Department")
public class Department implements Serializable {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;

   @OneToMany(mappedBy = "father",
        cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
   private List<Department> departments;
}

Когда я пытаюсь удалить бизнес-экземпляр, я получаю исключение Mysql.

Невозможно удалить или обновить родительскую строку: ограничение внешнего ключа не работает (evac_java.Department, CONSTRAINT FK_Department_Business FOREIGN KEY (Business) REFERENCES Business (Id)):HY000 - null

Это означает, что я не могу удалить бизнес-экземпляр, потому что с ним связаны отделы, но отдел не может существовать сам по себе, поэтому я хочу удалить все бизнес-отделы при его удалении. Я думал, что добьюсь этого, добавив cascade = CascadeType.REMOVE в аннотацию @OneToMany в бизнес-объекте, но это не работает.

Я провел поиск в сети и нашел много вопросов, похожих на этот, в stackoverflow, но все они предполагают одно и то же: add cascade = CascadeType.REMOVE или CascadeType.ALL

Поэтому мне интересно, если я что-то пропустил.

Я использую Glassfish 4.1 и EclipseLink.

я пробовал с

@OneToMany(mappedBy = "business", orphanRemoval = true)
private List<Department> departments;

на хозяйственном объекте, но он тоже не работает

Вот метод, который я использую для удаления сущностей, объявленных в абстрактном классе.

public void remove(T entity) {
    getEntityManager().remove(getEntityManager().merge(entity));
}
  • я думаю, вы должны добавить orphanremoval = true заголовок вашего списка, который вы хотите удалить элемент Sarkhan 19.04.2015
  • Я рассматривал этот вариант, но не является ли он избыточным с CascadeType.REMOVE, а также более агрессивным? и в этом случае это должно сработать, но что, если мне не нужно удалять детей? Armando 19.04.2015
  • если это отношение onetomany, это означает, что дети не могут существовать без отцовского класса. Поэтому, если вы удаляете отцовский класс, это означает, что вы должны удалить связанные элементы или обновить связанный столбец null Sarkhan 19.04.2015
  • stackoverflow.com/questions/18813341/ Sarkhan 19.04.2015
  • Вы пробовали использовать обе опции orphanRemoval и cascade? Удаление потерянных строк просто говорит об удалении потерянных строк (это поведение, которое вы хотите), а параметр каскада просто говорит, что нужно инициировать удаление при удалении стороны-владельца. Определены ли у вас какие-либо дополнительные FK, помимо того, что у вас есть здесь? Как выглядит сгенерированный DDL и какая реализация JPA? John Ament 20.04.2015
  • Я пробовал варианты "orphanRemoval" и "cascade". Я использую JPA 2.0 с EclipseLink на Glassfish 4.1. Я отредактировал свой вопрос, чтобы показать другие отношения. Armando 20.04.2015

javajpaeclipselinkjava-ee-7

Ответы

Ответ 1 · рейтинг 2 · Chris

JPA может удалять и каскадировать удаление только тех сущностей, о которых он знает, и если вы не поддерживали обе стороны этого двунаправленного отношения, возникнут подобные проблемы. Если коллекция отделов пуста, попробуйте em.refresh() перед удалением, заставив JPA заполнить все отношения, чтобы их можно было правильно удалить, хотя лучше поддерживать обе стороны отношения по мере внесения изменений, чтобы избежать удар по базе данных.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы