Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate: duplicate key value violates unique constraint

I am trying to insert into a new record to my postgresql using Hibernate and Java EE.

This is my model:

@Entity
@SuppressWarnings("serial")
@Inheritance(strategy=InheritanceType.JOINED)
public class BaseDesign implements Serializable {

    @Id
    @Expose
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;

    @Version
    @Column(name = "version")
    private int version;

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

    // getter and setter
}

And here is my import.sql

INSERT INTO basedesign (id, name, version) VALUES (1, 'China', 0);

When I build the code, the record is added into db.

However, when I try to add a new record using EntityManager, like this:

BaseDesign design = new BaseDesign();
design.setName("USA");                  
em.persist(design);

I got:

Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "basedesign_pkey"
  Detail: Key (id)=(1) already exists.

Execute the same command for second time, and it success.

Why do Hibernate not increment the starting ID at the first time? And how to configure it to start at the last inserted integer?

like image 686
VHanded Avatar asked May 29 '16 15:05

VHanded


People also ask

How do you fix duplicate key value violates unique constraint?

As a solution for your present problem, either delete the conflicting manually inserted rows or reset the sequence to a value higher than any existing id in the table.

What is aborted error duplicate key value violates unique constraint?

The “duplicate key violates unique constraint” error notifies the caller that a retry is needed. This seems like an intuitive approach, but relying on this optimistic insert can quickly have a negative performance impact on your database.


1 Answers

When you create a bigserial column in Postgresql, you are actually creating a sequence. When you manually inserted an ID value of '1', Postgresql did not update the sequence to take this into account. Hibernate lets Postgresql use the sequence to generate the ID, but the first value produced is '1', which clashes. The second value is fine.

If you created the problem by going behind Hibernate and using SQL directly, you should fix it the same way: use ALTER SEQUENCE to set the next value:

alter sequence basedesign_id_seq restart with 2;
like image 160
Adrian Cox Avatar answered Sep 29 '22 19:09

Adrian Cox