isA*_*Don 5 java spring hibernate spring-data
我有对 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);
}
Run Code Online (Sandbox Code Playgroud)
运行所有测试在大多数情况下都有效,但有时调用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".
Run Code Online (Sandbox Code Playgroud)
答案与答案翻译有以下关系:
@OneToMany(mappedBy = "answer", cascade = CascadeType.ALL)
private List<AnswerTranslation> translations = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
答案翻译为答案:
@ManyToOne
private Answer answer;
Run Code Online (Sandbox Code Playgroud)
如果没有答案,答案翻译就不可能存在。
我不明白为什么answerRepository.deleteAll(); 有时answerTranslationRepository会失败并显示错误,因为该方法应该在尝试删除答案之前从第一个数据中删除数据。
这是使用 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);
}
Run Code Online (Sandbox Code Playgroud)
你可以看看这个答案,里面有很好的解释。
| 归档时间: |
|
| 查看次数: |
19039 次 |
| 最近记录: |