Come annotare il campo autoincrement MYSQL con annotazioni JPA

Dritto al punto, il problema è salvare l’object Operator nel DB MySQL. Prima di salvare, provo a selezionare da questa tabella e funziona, quindi è la connessione a db.

Ecco il mio object Operatore:

@Entity public class Operator{ @Id @GeneratedValue private Long id; private String username; private String password; private Integer active; //Getters and setters... } 

Per salvare uso il metodo persist JPA EntityManager .

Ecco alcuni log:

 Hibernate: insert into Operator (active, password, username, id) values (?, ?, ?, ?) com.mysql[email protected]: insert into Operator (active,password, username, id) values (0, 'pass', 'user', ** NOT SPECIFIED **) 

Per come la vedo io, il problema è la configurazione con incremento automatico ma non riesco a capire dove.

Ho provato alcuni trucchi che ho visto qui: Hibernate non rispettando il campo chiave principale di auto_increment MySQL Ma niente di tutto ciò ha funzionato

Se sono necessari altri file di configurazione, li fornirò.

DDL:

 CREATE TABLE `operator` ( `id` INT(10) NOT NULL AUTO_INCREMENT, `first_name` VARCHAR(40) NOT NULL, `last_name` VARCHAR(40) NOT NULL, `username` VARCHAR(50) NOT NULL, `password` VARCHAR(50) NOT NULL, `active` INT(1) NOT NULL, PRIMARY KEY (`id`) ) 

Per utilizzare una colonna AUTO_INCREMENT MySQL, devi utilizzare una strategia IDENTITY :

 @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Long id; 

Che cosa otterresti usando AUTO con MySQL:

 @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; 

Che è in realtà equivalente a

 @Id @GeneratedValue private Long id; 

In altre parole, la tua mapping dovrebbe funzionare. Ma Hibernate dovrebbe omettere la colonna id nell’istruzione SQL insert, e non lo è. Ci deve essere una sorta di disallineamento da qualche parte.

Hai specificato un dialetto MySQL nella configurazione di Hibernate (probabilmente MySQL5InnoDBDialect o MySQL5Dialect seconda del motore che stai utilizzando)?

Inoltre, chi ha creato il tavolo? Puoi mostrare il DDL corrispondente?

Follow-up: non riesco a riprodurre il tuo problema. Usando il codice della tua quadro e il tuo DDL, Hibernate genera il seguente (previsto) SQL con MySQL:

 insert into Operator (active, password, username) values (?, ?, ?) 

Si noti che la colonna id è assente dall’istruzione precedente, come previsto.

Per riassumere, il codice, la definizione della tabella e il dialetto sono corretti e coerenti, dovrebbe funzionare. Se non fa per te, forse qualcosa non è sincronizzato (fai una build pulita, controlla due volte la directory di build, ecc.) O qualcos’altro è solo sbagliato (controlla i registri per qualcosa di sospetto).

Per quanto riguarda il dialetto, l’ unica differenza tra MySQL5Dialect o MySQL5InnoDBDialect è che in seguito aggiunge ENGINE=InnoDB agli oggetti tabella quando genera il DDL. L’utilizzo di uno o l’altro non modifica l’SQL generato.

Usando MySQL, solo questo approccio funzionava per me:

 @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Long id; 

Gli altri 2 approcci dichiarati da Pascal nella sua risposta non funzionavano per me.

Per chiunque stia leggendo questo che usa EclipseLink per JPA 2.0, ecco le due annotazioni che ho dovuto usare per far sì che JPA conservi i dati, dove “MySequenceGenerator” è il nome che vuoi dare al generatore, “myschema” è il nome del schema nel database che contiene l’object sequenza e “mysequence” è il nome dell’object sequenza nel database.

 @GeneratedValue(strategy= GenerationType.SEQUENCE, generator="MySequenceGenerator") @SequenceGenerator(allocationSize=1, schema="myschema", name="MySequenceGenerator", sequenceName = "mysequence") 

Per coloro che utilizzano EclipseLink (e possibilmente altri fornitori JPA), è CRITICO che si imposta l’attributo allocationSize in modo che corrisponda al valore INCREMENT definito per la sequenza nel database. In caso contrario, si verificherà un errore di persistenza generico e si sprecherà una grande quantità di tempo cercando di rintracciarlo, come ho fatto io. Ecco la pagina di riferimento che mi ha aiutato a superare questa sfida:

http://wiki.eclipse.org/EclipseLink/Examples/JPA/PrimaryKey#Using_Sequence_Objects

Inoltre, per dare un contesto, ecco cosa stiamo usando:

Java 7 Glassfish 3.1 PostgreSQL 9.1 PrimeFaces 3.2 / JSF 2.1

Inoltre, per pigrizia, l’ho creato in Netbeans con le procedure guidate per generare Entità da DB, Controllori da Entità e JSF da Entità, e le procedure guidate (ovviamente) non sanno come gestire le colonne ID basate su sequenza, quindi dovrai aggiungere manualmente queste annotazioni.

Assicurati che il tipo di dati id sia Long invece di String, se questo sarà stringa, allora l’annotazione @GeneratedValue non funzionerà e la sql genererà per

 @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private String id; create table VMS_AUDIT_RECORDS (id **varchar(255)** not null auto_increment primary key (id)) 

questo deve essere

 create table VMS_AUDIT_RECORDS (id **bigint** not null auto_increment primary key (id)) 

Ho provato ogni cosa, ma ancora non ero in grado di farlo, sto usando mysql, jpa con hibernate, ho risolto il problema assegnando il valore di id 0 nel costruttore seguente è il mio codice di dichiarazione id

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