Spring Data JPA难以理解的工作逻辑

时间:2018-07-31 12:32:00

标签: java spring-data-jpa spring-data spring-transactions

在使用中,我有这种方法:

...
Application.CutCopyMode = False
   Selection.Copy

Sheets("MainTable").Select
   Range("O5.Value:P5.Value").Select
   Selection.Insert Shift:=xlDown

   End Sub

在带有@Transactional public void CatalogRequest(CatalogDto catalogDto) { updateCatalog(catalogDto); } 注释的此方法中,我会校准内部私有方法

@Transactional

对于我来说,我的目录处于活动状态,我等待下一个逻辑:

  1. private void updateCatalog(CatalogDto catalogDto) { Catalog catalog = catalogsRepository.findByGuigAndIsActive(catalogDto.getGuid(), true); if (catalog != null) { catalog.setIsActive(false); catalogsRepository.save(catalog); } CatalogMapper catalogMapper = new CatalogMapper(catalogDto); Catalog newCatalog = catalogMapper.toDomain(); catalogsRepository.save(newCatalog); } 查找活动目录
  2. catalogsRepository.findByGuigAndIsActive-是
  3. 我设置了有效的if (catalog != null)并保存目录

    false
  4. 从dto创建新目录并将其保存为活动的真实状态。

但是我得到catalog.setIsActive(false); catalogsRepository.save(catalog); 是因为我有约束:

SQLIntegrityConstraintViolationException

我正在等待旧目录更改状态为不活动,更新以及插入具有活动状态的新目录。并在交易中

create unique index CATALOG_UN1
    on CATALOGS (CASE "IS_ACTIVE" WHEN 1 THEN "GUIG" WHEN 0 THEN NULL END)

但是,看来交易方式有所不同,或者我不了解。当我尝试插入具有活动状态JPA的新目录时,也认为旧的活动状态也为true,并抛出begin transaction oldCatalog.setActive(true) update oldCatalog create new catalog with active true insert new catalog commit 。我这样修复:

SQLIntegrityConstraintViolationException

但是我不明白我是否在做正确的事,为什么简单的if (catalog != null) { catalog.setIsActive(false); catalogsRepository.saveAndFlush(catalog); } 无效?

1 个答案:

答案 0 :(得分:2)

保存Managed Entity时,这意味着您正在更新从数据库中提取的Hibernate的实体,Hibernate不会发送更新查询到数据库,直到它尝试提交Transaction。因此,在您的情况下,如果您不强制Hibernate首先发送更新查询,则您的创建查询将在更新查询之前发送到数据库,并且数据库将发现约束冲突。这就是JDBC Driver引发异常的原因。

但是,当您使用saveAndFlush时,您会强制Hibernate将已缓存在其缓冲区中的所有查询发送到数据库,因此,当您保存新实体时,create query将是更新查询后发送到数据库。