gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 02:00:49 25 4
gpt4 key购买 nike

在服务中我有这个方法:

@Transactional
public void CatalogRequest(CatalogDto catalogDto) {

updateCatalog(catalogDto);

}

在这个带有@Transactional注释的方法中,我调用了内部私有(private)方法

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);
}

就我而言,我的目录处于 Activity 状态,我等待下一个逻辑:

  1. catalogsRepository.findByGuigAndIsActive 查找 Activity 目录
  2. if(目录!= null) - true
  3. 我设置了 Activity false并保存目录

    catalog.setIsActive(false);
    catalogsRepository.save(catalog);
  4. 从 dto 创建新目录并以有效 true 状态保存。

但是我得到 SQLIntegrityConstraintViolationException 因为我有约束:

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

我正在等待旧目录更改状态为不活动、更新和新目录插入为 Activity 状态。并且它在事务中

begin transaction
oldCatalog.setActive(true)
update oldCatalog
create new catalog with active true
insert new catalog
commit

但交易的工作方式似乎有所不同,或者我不明白某些事情。当我尝试插入具有 Activity 状态的新目录时,JPA 认为旧的 Activity 状态也为 true,并抛出 SQLIntegrityConstraintViolationException。我这样解决这个问题:

if (catalog != null) {
catalog.setIsActive(false);
catalogsRepository.saveAndFlush(catalog);
}

但我不明白我是否在做正确的事情以及为什么简单的 save() 不起作用。

最佳答案

当您保存托管实体时,这意味着您正在更新Hibernate从数据库获取的实体,Hibernate不会发送更新查询数据库,直到它尝试提交事务。因此,在您的情况下,如果您不强制 Hibernate 首先发送更新查询,您的创建查询将在更新查询之前发送到数据库,并且数据库将发现约束违规。这就是 JDBC 驱动程序 抛出异常的原因。

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

关于java - Spring Data JPA 难以理解的工作逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51613486/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com