所以我的客户=债权人,其中有文件清单。该列表每个文档只能包含一种类型,因此我有添加文档的方法,该方法添加了新的documnet,但是如果已经有此类型的文档,则应将其替换。
此测试由于唯一约束而失败
def "should replace documents with same type"() {
given:
def creditor = creditors.create(CreditorHelper.createSampleCreditorForm())
def documentType = DocumentTypeEvent.INVESTMENT_INSTRUCTION
and:
def old = documents.addDocument(new DocumentForm("urlOld", creditor.creditorReference, documentType, ZonedDateTime.now()))
when:
documents.addDocument(new DocumentForm("urlNew", creditor.creditorReference, documentType, ZonedDateTime.now()))
then:
def newResult = documentRepository.findByCreditorReference(creditor.creditorReference)
newResult.size() == 1
newResult.find {
it.url == "urlNew"
}
and:
documentRepository.findByHash(old.hash) == Optional.empty()
}
implementaion是简单替换:
@Transactional
public Document addDocument(final DocumentForm documentForm) {
return creditorRepository.findByCreditorReferenceIgnoreCase(documentForm.getCreditorReference())
.addDocument(new Document(documentForm));
}
通话上方:
public Document addDocument(Document newDocument) {
documents.removeIf(existingDocument -> existingDocument.getType() == newDocument.getType());
documents.add(newDocument);
}
实体:
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "creditor_id")
@Builder.Default
private List<Document> documents = new ArrayList<>();
有趣的是,当我从飞行路线测试中删除唯一约束时,通过似乎就出现了交易问题。
答案 0 :(得分:0)
我认为这可能与刷新期间Hibernate的查询顺序有关。由于持久化新实体是由Hibernate的会话作为第一操作调用的,因此在刷新期间DB中存在实体时会出现异常。在Hibernate中打开show_sql
选项,然后尝试查看日志,发送给数据库的查询的真实顺序是什么。
还阅读了弗拉德(Vlad)关于订购的文章:A beginner’s guide to Hibernate flush operation order。您还可以阅读类EventListenerRegistryImpl
的代码,并查看顺序。