测试中列表中的替换项违反了唯一约束

时间:2019-07-04 15:17:24

标签: java spring hibernate spring-boot testing

所以我的客户=债权人,其中有文件清单。该列表每个文档只能包含一种类型,因此我有添加文档的方法,该方法添加了新的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<>();

有趣的是,当我从飞行路线测试中删除唯一约束时,通过似乎就出现了交易问题。

1 个答案:

答案 0 :(得分:0)

我认为这可能与刷新期间Hibernate的查询顺序有关。由于持久化新实体是由Hibernate的会话作为第一操作调用的,因此在刷新期间DB中存在实体时会出现异常。在Hibernate中打开show_sql选项,然后尝试查看日志,发送给数据库的查询的真实顺序是什么。

还阅读了弗拉德(Vlad)关于订购的文章:A beginner’s guide to Hibernate flush operation order。您还可以阅读类EventListenerRegistryImpl的代码,并查看顺序。