我的系统有一个 * patient * 实体,其中包含email(字符串)、type(整数)字段,这两个字段都是非主字段、非唯一字段和非空字段以及其他字段,当然还有主键ID。
保存新的患者实体后,当我通过jpa query * findById * 在数据库中搜索实体时,它运行良好,并获取几毫秒前刚刚保存的新实体。
但是,当我按电子邮件搜索新保存的实体并按jpa查询类型 * findByEmailAndTypeAndEmailIsNotNull * 时,它什么也不返回,但如果我在保存新实体1秒后运行完全相同的 * findByEmailAndTypeAndEmailIsNotNull * 查询,它将返回新保存的实体。
有人能诊断出这个问题吗?它甚至与JPA有关吗?还是与数据库本身有关?
编辑:
public synchronized Patient addPatient(PatientProfileDto patientProfileDto, Integer facilityId)
throws ResourceAlreadyExistsException, EntityNotFoundException, ClientException {
// some code
performPatientCreationValidations(ownerDto, ownerDemographicDto.getNationality().getId(), Boolean.FALSE, Boolean.FALSE);
// patient creation
patientRepository.saveAndFlush(patient);
// some code to link patient to other entities
}
private void performPatientCreationValidations(...params)
throws ResourceAlreadyExistsException, ClientException {
if (patientRepository.findByEmailAndTypeAndEmailIsNotNull(patientDto.getEmail(), PatientType.OWNER.getId()).isPresent()) {
// throw error
}
}
如果我连续点击API 5次,延迟可忽略,则会创建2个重复患者,但在最后3次API点击时,它会抛出错误。在收到第2次API点击时,它也应抛出错误。还应注意,患者的添加是同步函数,因此当一次API点击完成保存患者时,另一次API点击将获得函数n的锁定,继续。
1条答案
按热度按时间sy5wg1nm1#
保存新的患者实体后,当我通过jpa查询findById在数据库中搜索实体时,它运行得非常好
JpaRepository.findById()
可以很好地工作,因为它从Hibernate的一级缓存中获取实体,而不是从数据库中获取实体,因为插入数据库通常被推迟到必要的时候,例如,直到会话被刷新。因此,您必须使用
JpaRepository.flush()
手动刷新会话,或者使用JpaRepository.saveAndFlush()
而不是JpaRepository.save()
,或者在一个事务中执行操作,在这种情况下,您的请求共享一个会话,并且Hibernate将在获得针对同一实体的新查询后立即刷新其缓存。