2010-11-04 68 views
75

Directamente al punto, el problema es guardar el objeto Operator en MySQL DB. Antes de guardar, trato de seleccionar de esta tabla y funciona, así como la conexión a db.Cómo anotar campo de autoincrement de MYSQL con anotaciones JPA

Aquí es mi objeto del operador:

@Entity 
public class Operator{ 

    @Id 
    @GeneratedValue 
    private Long id; 

    private String username; 

    private String password; 


    private Integer active; 

    //Getters and setters... 
} 

Para guardar utilizo persist método APP EntityManager ‘s.

Aquí es un poco de registro:

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

La forma en que lo veo, es un problema de configuración con incremento automático, pero no puedo averiguar dónde.

probado algunos trucos que he visto aquí: Hibernate not respecting MySQL auto_increment primary key field Pero nada de eso funcionó

Si cualquier otro archivo de configuración necesarios que les proporcionará.

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`) 
) 
+0

¿Qué versión de Hibernate estás usando? –

+0

Hibernate 3.2.4 – trivunm

Respuesta

110

Para utilizar una columna MySQL AUTO_INCREMENT, que se supone que usar una estrategia IDENTITY:

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

¿Qué es lo que se obtiene cuando se utiliza AUTO con MySQL:

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

que en realidad es equivalente a

@Id @GeneratedValue 
private Long id; 

En otras palabras, su asignación debería funcionar. Pero Hibernate debe omitir la columna id en la instrucción de inserción SQL, y no lo es. Debe haber una especie de desajuste en alguna parte.

¿Especificó un dialecto MySQL en su configuración de Hibernate (probablemente MySQL5InnoDBDialect o MySQL5Dialect según el motor que esté utilizando)?

Además, ¿quién creó la tabla? ¿Puedes mostrar el DDL correspondiente?

Seguimiento: No puedo reproducir su problema. Utilizando el código de su entidad y su DDL, Hibernate genera el SQL siguiente (esperado) con MySQL:

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

Tenga en cuenta que la columna de la id está ausente de la declaración anterior, como se esperaba.

En resumen, su código, la definición de la tabla y el dialecto son correctos y coherentes, debería funcionar. Si no es así, tal vez algo no esté sincronizado (realice una compilación limpia, revise el directorio de compilación, etc.) o algo diferente simplemente esté mal (revise los registros para detectar cualquier cosa sospechosa).

En cuanto el dialecto, la única diferencia entre MySQL5Dialect o MySQL5InnoDBDialect es que cuanto más tarde se suma ENGINE=InnoDB a los objetos de tabla al generar el DDL. El uso de uno u otro no cambia el SQL generado.

+0

Pascal, tienes razón al respecto, pero algo en mis archivos de configuración simplemente no es correcto. ¿Alguna otra sugerencia tal vez, ahora que he puesto nueva información y archivos de configuración? – trivunm

+9

@Pascal - He encontrado que necesitaba @GeneratedValue (strategy = GenerationType.IDENTITY) para hacer que AUTO_INCREMENT funcione correctamente cuando utilizo JPA 2/Hibernate 4.0.0.CR2/JBoss AS 7. http://bit.ly/ tdNyOJ –

+4

Tenga en cuenta que esto es cierto para ** MySQL **. Con ** PostgreSQL ** no obtienes '@GeneratedValue (strategy = GenerationType.IDENTITY)' cuando escribes '@GeneratedValue (strategy = GenerationType.AUTO)' y '@ GeneratedValue'. Así que ten cuidado y trata de ser prolijo. – sajjadG

11

Para cualquiera que lea esto y que esté usando EclipseLink para JPA 2.0, estas son las dos anotaciones que tuve que usar para que JPA persistiera en los datos, donde "MySequenceGenerator" es el nombre que quiera darle al generador, "myschema" es el nombre del esquema en su base de datos que contiene el objeto de secuencia, y "mysequence" es el nombre del objeto de secuencia en la base de datos.

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

Para aquellos que utilizan EclipseLink (y posiblemente otros proveedores JPA), es fundamental que se establece el atributo allocationSize para que coincida con el valor de incremento definido para su secuencia en la base de datos. Si no lo haces, obtendrás una falla de persistencia genérica y perderás bastante tiempo intentando rastrearla, como hice yo. Esta es la página de referencia que me ayudó a superar este desafío:

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

Además, para poner en contexto, esto es lo que estamos usando:

Java 7 Glassfish 3.1 PostgreSQL 9.1 3.2 PrimeFaces/JSF 2.1

Además, por la pereza, construí esto en Netbeans con los asistentes para generar Entidades de DB, Controladores de Entidades, y JSF de Entidades, y los asistentes (obviamente) no saben cómo lidiar con secuencia columnas de ID basadas en ce, por lo que tendrá que agregar manualmente estas anotaciones.

19

El uso de MySQL, solamente este enfoque estaba trabajando para mí:

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

Los otros 2 enfoques establecidos por Pascal en su respuesta no estaban trabajando para mí.

+0

Sí, lo arbitre en mi pregunta/respuesta. http: // stackoverflow.com/questions/39675714/schema-validation-missing-table-hibernate-sequences/39675802 # 39675802 –

3

Por favor asegúrese de que tipo de datos id es largo en lugar de cuerdas, si eso habrá cadena continuación anotación @GeneratedValue no funcionará y la generación de SQL para

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

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

que debe ser

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