Duplicate entry '[X]' for key '[Y]' on JPA repository 'save' operation. Saved entity has its key defined already

2.5k Views Asked by At

From what I understand, the 'save' function in a JPA repository should automatically do an update if a row with a provided key already exists. However, I'm getting errors that make it seem like it's trying to do a blind insert operation instead of an update. I'm at a bit of a loss here.

My entity looks like this:

@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
}

I have a simple repository:

@Repository
public interface InquiryRecordRepository extends CrudRepository<InquiryRecordEntity, Integer> {
}

And am trying to do an update on an object like this:

@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);
    }

But where I expect it to just overwrite the previous value, it throws an error:

[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

Am I missing something here?

1

There are 1 best solutions below

0
On

Do a quick check on the object identity of the inquiry object you are trying to save.

Just after this line

InquiryRecordEntity inquiry = inquiryRecordRepository.findOne(response.getInquiryId());

Examine the value of System.identityHashCode(inquiry) - save it as objId1

Just after this line

inquiry.setStatus(InquiryRecordEntity.InquiryStatus.CONCLUDED);

Examine the value of System.identityHashCode(inquiry) - save it as objId2

If objId1 is not the same as objId2 then you are trying to save another object with the same values, this is why an INSERT is occurring and any unique keys values will throw a ConstraintViolationException. Check where this is happening in the code and fix this bug. It should not be using/creating a different object.

If objId1 is same as objId2 then something is wrong with how you are manipulating the state of this object. Check if the id of the inquiry object is getting cleared.