据我了解,如果包含提供的键的行已存在,JPA存储库中的“保存”功能应自动进行更新。但是,我收到一些错误,使其似乎尝试执行盲目insert操作而不是进行更新。我在这里有点茫然。

我的实体看起来像这样:

@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是否被清除。

10-07 20:01
查看更多