我有测试在API上进行CRUD操作。在每次测试之前,API中的测试数据将被重新创建。意味着删除数据库中的所有数据并再次插入测试数据。
public void initDatabase() {
answerTranslationRepository.deleteAll();
answerRepository.deleteAll();
userRepository.deleteAll();
//....
Answer answer = new Answer();
AnswerTranslation answerTranslation = new AnswerTranslation("test", answer);
//....
answerTranslationRepository.save(answerTranslation);
answerRepository.save(answer);
}
运行所有测试的时间大多数但是时不时调用answerRepository.deleteAll();
失败了:
2018-04-01 09:09:49.069 ERROR 14260 --- [ main] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [fkco3o4hxryohduthxj2vgnuhxs]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259)
//.....
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:536)
... 54 more
Caused by: org.postgresql.util.PSQLException: ERROR: update or delete on table "answer" violates foreign key constraint "fkco3o4hxryohduthxj2vgnuhxs" on table "answer_translation"
Detail: Key (id)=(ab54d53a-cd55-428a-aac7-40b20ead86de) is still referenced from table "answer_translation".
答案与AnswerTranslation有以下关系:
@OneToMany(mappedBy = "answer", cascade = CascadeType.ALL)
private List<AnswerTranslation> translations = new ArrayList<>();
回答翻译答案:
@ManyToOne
private Answer answer;
如果没有答案,则不能存在AnswerTranslation。
我无法理解为什么answerRepository.deleteAll();
有时因显示的错误而失败,因为该方法应首先从answerTranslationRepository
删除数据,然后再尝试删除答案。
答案 0 :(得分:2)
当您使用JPA Hibernate时,这是一个常见问题。数据库查询执行不是从代码中顺序翻译的。从数据库表中删除条目后,只需调用flush()
即可。
因此修改后的函数应如下所示。
public void initDatabase() {
answerTranslationRepository.deleteAll();
answerTranslationRepository.flush();
answerRepository.deleteAll();
answerRepository.flush();
userRepository.deleteAll();
userRepository.flush();
//....
Answer answer = new Answer();
AnswerTranslation answerTranslation = new AnswerTranslation("test", answer);
//....
answerTranslationRepository.save(answerTranslation);
answerRepository.save(answer);
}
你可以在this answer看看这里有一个很好的解释。