2016-05-29 51 views
5

Sto tentando di inserire un nuovo record nel mio postgresql utilizzando Hibernate e Java EE.Ibernazione: valore chiave duplicato viola il vincolo univoco

Questo è il mio modello:

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

Ed ecco la mia import.sql

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

Quando costruisco il codice, il record viene aggiunto nella db.

Tuttavia, quando si tenta di aggiungere un nuovo record utilizzando EntityManager, in questo modo:

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

ho ottenuto:

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

eseguire lo stesso comando per la seconda volta, ed è successo.

Perché Hibernate non incrementa l'ID iniziale alla prima volta? E come configurarlo per iniziare all'ultimo numero intero inserito?

risposta

7

Quando si crea una colonna bigserial in Postgresql, è are actually creating a sequence. Quando hai inserito manualmente un valore ID di "1", Postgresql non ha aggiornato la sequenza per tenerne conto. Hibernate consente a Postgresql di utilizzare la sequenza per generare l'ID, ma il primo valore prodotto è '1', che si scontra. Il secondo valore va bene.

Se è stato creato il problema andando dietro Hibernate e usare direttamente SQL, si dovrebbe risolvere il problema nello stesso modo: use ALTER SEQUENCE to set the next value:

alter sequence basedesign_id_seq restart with 2; 
+0

Quindi questa soluzione deve assegnare un numero di nota ad esso? Non può raccogliere automaticamente l'ultimo ID? – VHanded

+1

Il problema è l'istruzione dell'inserto SQL che ha inserito manualmente un ID. Il sistema può prelevare automaticamente gli ID, a condizione che * sempre * lasci che il sistema generi l'ID e non fornisca mai un valore per la colonna id. –

+0

Grazie. Quello che sto cercando di ottenere è un backup e ripristino. Quando si genera un file di dump da DB, viene fornito con INSERT con ID in esso. Poiché tale ID non è generato da DB, ha causato il problema sopra riportato. – VHanded