Не удаляется объект при связи @OneToMany Java Hibernate

201
23 июля 2018, 22:10

Не могу понять в чем может быть ошибка при удалении

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (quizzes.question, CONSTRAINT FK_d96vtjbes71xkfbiwibobmopd FOREIGN KEY (id_quiz) REFERENCES quiz (id))

В классе Quiz такие связи:

 @OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Question> questions =new TreeSet();

В классе Question такие:

@OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Answer> answer;
    @ManyToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
    @JoinColumn(name = "id_quiz")
    private Quiz quiz;

В Answer:

   @ManyToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
    @JoinColumn(name = "id_question")
    private Question question;

Пробовал добавлять question в quiz двумя способами:(Ошибка в двух способах та же)

 Question question=new Question(titleQuiestion,answerList);
 quizService.getCurrentQuiz().getQuestions().add(question);
 serviceQuiz.update(quizService.getCurrentQuiz());
 // questionService.persist(question); //Второй способ, но при создании в конструкторе еще пишется владелец- в данном случае quizService.getCurrentQuiz()

Полагаю, что это происходит из-за смежной таблицы или из-за того, что не правильно использовал каскад в аннотациях. Но точно понять не могу, буду рад любой помощи!

Таким образом у меня происходит добавление

@Service
 abstract class HibServiceEntity<T, Id extends Serializable> {
 public void persist(T entity) {
        daoEntity.openCurrentSessionwithTransaction();
        daoEntity.persist(entity);
        daoEntity.closeCurrentSessionwithTransaction();
    }
@Controller
public class QuestionController {
     @RequestMapping(method=POST, value="questions/newquestion")
        public String postAddQuestion(Model model,
                                      @RequestParam("titileOfQuestion") String titleOfQuestion,
                                      @RequestParam("answers") String answerLine,
                                      @RequestParam("rightanswers") String rightAnswers){
            StringTokenizer tokzer=new StringTokenizer(answerLine, "\n");
            List<Answer> answerList=new ArrayList<>();
            while (tokzer.hasMoreTokens()) {
                answerList.add(new Answer(tokzer.nextToken().trim()));
            }
            tokzer=new StringTokenizer(rightAnswers, "\n");
            for (int i=0;tokzer.hasMoreTokens();i++) {
                answerList.get(i).setRight(Boolean.parseBoolean(tokzer.nextToken().trim()));
            }
            Question qu=new Question(titleOfQuestion,answerList);
            quizService.getCurrentQuiz().getQuestions().add(qu);
            quizServiceHib.update(quizService.getCurrentQuiz());
            return "redirect:/questions";
        }

Так происходит удаление:

 public void delete(T entity){
        getCurrentSession().delete(entity);
    }
    public List<T> findAll(){
        List<T> collection = (List<T>) getCurrentSession().createQuery("from "+getGenericType().getSimpleName()).list();
        return collection;
    }
@Controller
public class QuestionController {
    @RequestMapping(method = GET, value ="questions/removequestion/{id}")
        public String getRemoveQuestion(@PathVariable("id") int id){
            questionServiceHib.delete(id);
            return "redirect:/questions";
        }
Answer 1
  1. меняем тип EAGER на LAZY
  2. встраиваем фильтр OpenInViewEntityManager
  3. уберите JoinColum, хибер сам поймет как ему нужно вытягивать данные
  4. организовывайте работу через JPARepository
  5. удаление и добавление элементов производите так же как и в случаи с коллекциями и если у Вас не statles приложение то достаточно будет вызвать для обновления сущности в базе repository.save(entity)

P.S. снесите полностью реализацию работы с сессиями и транзакциями, предоставьте все это ORM и репозиториям, имхо удобно

READ ALSO
Проблема получение данных с сайта

Проблема получение данных с сайта

Занимаюсь получением http запроса, я вроде как пробился на сайт, но получаю след ошибки:

198
Загрузка больших файлов через REST API

Загрузка больших файлов через REST API

Я пишу файловое хранилище и хочу улучшить его работуЗагружаются файлы большого размера, кроме этого, после загрузки надо запретить их изменение,...

186
Как сделать 2 запроса в rx java?

Как сделать 2 запроса в rx java?

Есть 2 сервисаНезависимые у и каждого свои модели ответа

199