据我了解,如果具有所提供 key 的行已存在,JPA 存储库中的“保存”功能应自动进行更新。但是,我收到错误,使其看起来像是在尝试执行盲目的插入操作而不是更新操作。我在这里有点不知所措。
我的实体如下所示:
@Entity
@Data
@Table(name = "inquiry_record")
@NoArgsConstructor
public class InquiryRecordEntity {
@Id
@Column(name = "inquiry_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer inquiryId;
//Lots more fields down below, not important, no other keyed columns
}
我有一个简单的存储库:
@Repository
public interface InquiryRecordRepository extends CrudRepository<InquiryRecordEntity, Integer> {
}
我正在尝试对这样的对象进行更新:
@Transactional
public void receiveResponse(SomeUpdateResponse response) {
log.info("Received responsefor inquiry: {}", safeSerialize(response));
InquiryRecordEntity inquiry = inquiryRecordRepository.findOne(response.getInquiryId());
/*...
A bunch of stuff happens here, determining the value of 'inquiryComplete'.
...*/
if (inquiryComplete) {
inquiry.setStatus(InquiryRecordEntity.InquiryStatus.CONCLUDED);
inquiryRecordRepository.save(inquiry);
}
但是当我期望它只覆盖以前的值时,它会抛出错误:
[ERROR] o.h.e.jdbc.spi.SqlExceptionHelper - Duplicate entry '113' for key 'uk_tm_inquiry_id'
[ERROR] c.s.f.c.a.ApiControllerExceptionHandler - org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [uk_tm_inquiry_id]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [uk_tm_inquiry_id]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
我在这里遗漏了什么吗?
最佳答案
快速检查您尝试保存的查询对象的对象标识。
就在这一行之后
InquiryRecordEntity inquiry = inquiryRecordRepository.findOne(response.getInquiryId());
检查 System.identityHashCode(inquiry) 的值 - 将其保存为 objId1
就在这一行之后
inquiry.setStatus(InquiryRecordEntity.InquiryStatus.CONCLUDED);
检查 System.identityHashCode(inquiry) 的值 - 将其保存为 objId2
如果objId1与objId2不同,那么您正在尝试保存具有相同值的另一个对象,这就是发生INSERT并且任何唯一键值都会抛出ConstraintViolationException的原因。检查代码中发生这种情况的位置并修复此错误。它不应该使用/创建不同的对象。
如果objId1与objId2相同,那么您操作该对象状态的方式就有问题。检查查询对象的id是否被清除。
关于java - JPA 存储库 '[X]' 操作上的 key '[Y]' 重复条目 'save'。保存的实体已定义其键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30737290/