gpt4 book ai didi

java - Spring数据-根据先前的插入插入数据

转载 作者:搜寻专家 更新时间:2023-11-01 03:03:44 24 4
gpt4 key购买 nike

我需要将数据保存到 2 个表(一个实体表和一个关联表)中。我只是使用实体存储库中的 save() 方法保存我的实体。然后,为了性能,我需要将行插入到 native sql 中的关联表中。这些行引用了我之前保存的实体。问题来了:我得到一个关于外键的完整性约束异常。在第二次查询中不知道首先保存的实体。

这是我的代码:

repo :

public interface DistributionRepository extends JpaRepository<Distribution, Long>, QueryDslPredicateExecutor<Distribution> {

@Modifying
@Query(value = "INSERT INTO DISTRIBUTION_PERIMETER(DISTRIBUTION_ID, SERVICE_ID) SELECT :distId, p.id FROM PERIMETER p "
+ "WHERE p.id in (:serviceIds) AND p.discriminator = 'SRV' ", nativeQuery = true)
void insertDistributionPerimeter(@Param(value = "distId") Long distributionId, @Param(value = "serviceIds") Set<Long> servicesIds);
}

服务:

@Service
public class DistributionServiceImpl implements IDistributionService {

@Inject
private DistributionRepository distributionRepository;

@Override
@Transactional
public DistributionResource distribute(final DistributionResource distribution) {

// 1. Entity creation and saving
Distribution created = new Distribution();
final Date distributionDate = new Date();
created.setStatus(EnumDistributionStatus.distributing);
created.setDistributionDate(distributionDate);
created.setDistributor(agentRepository.findOne(distribution.getDistributor().getMatricule()));
created.setDocument(documentRepository.findOne(distribution.getDocument().getTechId()));
created.setEntity(entityRepository.findOne(distribution.getEntity().getTechId()));
created = distributionRepository.save(created);

// 2. Association table
final Set<Long> serviceIds = new HashSet<Long>();
for (final ServiceResource sr : distribution.getServices()) {
serviceIds.add(sr.getTechId());
}

// EXCEPTION HERE
distributionRepository.insertDistributionPerimeter(created.getId(), serviceIds);
}
}

这 2 个查询似乎在不同的事务中,而我设置了 @Transactionnal 注释。我还尝试使用 entityManager.createNativeQuery() 执行我的第二个查询并得到相同的结果...

最佳答案

在执行 native 查询或使用 saveAndFlush 之前调用 entityManager.flush()

根据你的具体情况我会推荐使用

created = distributionRepository.saveAndFlush(created);

重要提示:您的“ native ”查询必须使用相同的事务! (或者你现在需要一个事务隔离级别)


你还写道:

I don't really understand why the flush action is not done by default

刷新由 Hibernate 处理(可以配置,默认为“自动”)。这意味着 hibernate 将在任何时间点刷新数据。但始终在您通过 HIBERNATE 提交事务或执行其他 SQL 语句之前。 - 所以通常这没有问题,但在您的情况下,您使用 native 查询绕过 hibernate ,因此 hibernate 将不知道此语句,因此它不会刷新其数据。

另见我的回答:https://stackoverflow.com/a/17889017/280244关于这个话题

关于java - Spring数据-根据先前的插入插入数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29825290/

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