Hibernate - Uplicate key value violates Unique Constraint

Asked

Viewed 3,905 times

3

I have the following problem:

Person:

@Entity
@Table(name="tb_pessoa", schema="public")
@Inheritance(strategy = InheritanceType.JOINED)
public class Pessoa implements Serializable {
   private static final long serialVersionUID = 1L;

   @Id
   @SequenceGenerator(name = "tb_pessoa_id_seq", sequenceName = "tb_pessoa_id_seq", schema="public")
   @GeneratedValue(strategy = GenerationType.AUTO, generator = "tb_pessoa_id_seq")
   @Column(name = "id", nullable = false)
   private Integer id;

   ...

Pessoa Fisica:

@Entity  
@Table(name="tb_pessoafisica", schema="public")
@PessoaFisicaAnnotation
@PrimaryKeyJoinColumn(name = "id")
public class PessoaFisica extends Pessoa implements Serializable {
   private static final long serialVersionUID = 1L;

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

   ...

Supposing on the table Person has records with id from 1 to 500. When I execute the code below:

PessoaFisica pessoaFisica = new PessoaFisica();
pessoaFisica.setEmail("[email protected]");

...

em.persist(pessoa);

The following error is happening:

17:26:13,613 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--10.36.1.49-8180-1) ERROR: duplicate key value violates unique constraint "tb_pessoa_pkey"
    Detalhe: Key (id)=(438) already exists.
17:26:13,614 WARN  [com.arjuna.ats.arjuna] (http--10.36.1.49-8180-1) ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - failed for SynchronizationImple< 0:ffff7f000101:-7f6ae4e3:558080ed:4f, org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization@331af73a >: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: ERROR: duplicate key value violates unique constraint "tb_pessoa_pkey"
  Detalhe: Key (id)=(438) already exists.

I haven’t been able to figure out why you’re trying to use the id 438 and not 501

Does anyone know what might be going on?

Thank you very much

CREATE TABLE tb_pessoa
(
    id integer NOT NULL,
    CONSTRAINT tb_pessoa_pkey PRIMARY KEY (id)
)

CREATE TABLE tb_pessoafisica
(
    email character varying(64) NOT NULL,
    CONSTRAINT tb_pessoafisica_pkey PRIMARY KEY (id),
    CONSTRAINT fkee8c050f70415778 FOREIGN KEY (id)
        REFERENCES tb_pessoa (id) MATCH SIMPLE
)

CREATE SEQUENCE tb_pessoa_id_seq
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 500
  CACHE 1;

Log Hibernate:

07:50:52,463 INFO  [stdout] (http--10.36.1.49-8180-2) Hibernate: 
07:50:52,463 INFO  [stdout] (http--10.36.1.49-8180-2)     select
07:50:52,464 INFO  [stdout] (http--10.36.1.49-8180-2)         nextval ('public.tb_pessoa_id_seq')
07:50:52,497 INFO  [stdout] (http--10.36.1.49-8180-2) Hibernate: 
07:50:52,498 INFO  [stdout] (http--10.36.1.49-8180-2)     insert 
07:50:52,499 INFO  [stdout] (http--10.36.1.49-8180-2)     into
07:50:52,499 INFO  [stdout] (http--10.36.1.49-8180-2)         public.tb_pessoa
07:50:52,500 INFO  [stdout] (http--10.36.1.49-8180-2)         (id) 
07:50:52,500 INFO  [stdout] (http--10.36.1.49-8180-2)     values
07:50:52,501 INFO  [stdout] (http--10.36.1.49-8180-2)         (?)
07:50:52,519 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--10.36.1.49-8180-2) SQL Error: 0, SQLState: 23505
07:50:52,521 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--10.36.1.49-8180-2) ERROR: duplicate key value violates unique constraint "tb_pessoa_pkey"
    Detalhe: Key (id)=(438) already exists.

1 answer

4


Considering your ORM, Hibernate will execute a query to retrieve the next value of tb_pessoa_id_seq before including the new record, something of this kind:

select nextval ('tb_pessoa_id_seq')

Quoting what you said yourself:

Suppose the Person table has records with an id from 1 to 500.

Well, if you check the starting value on your quence is 467 (START 467), that is, the next will be 468, which is returned in the query by the next value of the quence.

To fix this you can run something that changes the start value of quence, something like that:

ALTER SEQUENCE tb_pessoa_id_seq RESTART WITH 501;
  • Bruno, thank you so much for your reply. Really the beginning of my Quence was "wrong" in the example. I changed to 500 now the start to try to "explain" better my problem.

  • The problem still remains, because if I try to persist the entity instead of using the latter id + 1 (501) is with 438.

  • @Mamga include the Hibernate log, with queries generated when inserting

  • Hello @Bruno-César - including the Hibernate log... Thank you.

  • @Mamga is sure that in the database the quence is correct? I simulated your case and it’s right, just changed. Maybe it’s interesting to include a reproducible example to see.

  • I don’t know what else to say. I started from scratch again to see if there was something wrong in my source, the bank continued the same, and when I went to persist a record happened the same thing. The Ibernate uses the select nextval ('public.tb_pessoa_id_seq') if I copy and paste this command in pgadmin it returns the correct value. But in Hibernate it does not.

  • @Mamga is connecting to the right server/base, right? Already tried to create a new base?

  • Solved, I still do not understand why, but with a help includes the allocationSize = 1 in the @SequenceGenerator and it’s working again. Thank you

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.