Java Spring数据JPA不可理解的工作逻辑
在服务中,我有以下方法:Java Spring数据JPA不可理解的工作逻辑,java,spring-data-jpa,spring-data,spring-transactions,Java,Spring Data Jpa,Spring Data,Spring Transactions,在服务中,我有以下方法: @Transactional public void CatalogRequest(CatalogDto catalogDto) { updateCatalog(catalogDto); } 在此方法中,使用@Transactional注释调用内部私有方法 private void updateCatalog(CatalogDto catalogDto) { Catalog catalog = catalogsRepository.findByGuig
@Transactional
public void CatalogRequest(CatalogDto catalogDto) {
updateCatalog(catalogDto);
}
在此方法中,使用@Transactional
注释调用内部私有方法
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);
}
在我的情况下,目录处于活动状态,我等待下一个逻辑:
catalogsRepository.findbyguidandisactive
find active catalogif(catalog!=null)
-truefalse
并保存目录
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)
我正在等待旧目录更改状态为“非活动”、“更新”,以及新目录插入状态为“活动”。它在交易中
begin transaction
oldCatalog.setActive(true)
update oldCatalog
create new catalog with active true
insert new catalog
commit
但看起来这项交易的运作方式有所不同,或者我不明白什么。当我尝试插入具有活动状态的新目录时,JPA认为旧的活动状态也为true,并抛出SQLIntegrityConstraintViolationException
。我是这样解决的:
if (catalog != null) {
catalog.setIsActive(false);
catalogsRepository.saveAndFlush(catalog);
}
但我不明白我做的是否正确,以及为什么simple
save()
不起作用。当您保存一个托管实体时,这意味着您正在更新一个从数据库获取的Hibernate
实体,Hibernate
在尝试提交事务之前不会向数据库发送更新查询。因此,在您的情况下,如果您不强制Hibernate
首先发送更新查询,那么您的create查询将在更新查询之前发送到数据库,数据库将发现约束冲突。这就是为什么JDBC驱动程序
抛出异常的原因
但是当您使用saveAndFlush
时,您会强制Hibernate
将缓存在其缓冲区中的所有查询发送到数据库,因此,当您保存新实体时,在更新查询之后,将创建查询发送到数据库 当您保存一个托管实体
时,这意味着您正在更新从数据库获取的Hibernate
实体,Hibernate
不会向数据库发送更新查询,直到它尝试提交事务
。因此,在您的情况下,如果您不强制Hibernate
首先发送更新查询,那么您的create查询将在更新查询之前发送到数据库,数据库将发现约束冲突。这就是为什么JDBC驱动程序
抛出异常的原因
但是当您使用saveAndFlush
时,您会强制Hibernate
将缓存在其缓冲区中的所有查询发送到数据库,因此,当您保存新实体时,在更新查询之后,将创建查询发送到数据库 如果我插入一条新记录,我将收到一个错误,事务将回滚我的更新saveAndFlush?会出现什么异常?您可以发送从数据库中得到的错误吗?如果我插入一条新记录,我将收到一个错误,事务将回滚我的更新saveAndFlush?您会得到什么异常?您可以发送从数据库中得到的错误吗?