Home > Software design >  JPA: Data integrity violation instead of Upsert
JPA: Data integrity violation instead of Upsert

Time:05-07

I have this entity with these fields and this primary key:

@Getter
@Setter
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "MY_TABLE", schema = "MY_SCHEME")
public class MyEntity{

    @Id
    @Column(name = "ID")
    private String id;

    @Column(name = "NAME")
    private String name;

    @Column(name = "DESCRIPTION")
    private String description;

}

I'm experiencing some undesirable behavior.If I try to insert the exact same data, I was expecting a primary key violation because it already exists, but I'm finding that what it's doing is an upsert. I am extending my repository from JpaRepository and using the save method:

@Repository
public interface MyJpaRepository extends JpaRepository<MyEntity, String> {

}

In my service:

...
this.repository.save(myEntity);
...

The database is Oracle, and if I launch the insert manually in SQL developer, the data violation occurs.

That could be happening?

CodePudding user response:

Based on source code of save:

public <S extends T> S save(S entity) {

        Assert.notNull(entity, "Entity must not be null.");

        if (entityInformation.isNew(entity)) { //it checks if entity is new based on id. i.e. insert operation.
            em.persist(entity);
            return entityx
        } else {
            return em.merge(entity); // just merging i.e. in your case doing upsert.
        }
    }

So currently save method works as expected; but if you really want to avoid upsert behaviour you might want to try using existsById; something like below:

if(!repository.existsById(..)){
    repository.save(..);
}
  • Related