java - generatedvalue - Cómo anotar el campo de autoincrementación de MYSQL con anotaciones JPA
java jpa example (5)
Asegúrese de que el tipo de datos de ID sea Largo en vez de Cadena, si eso será una cadena, entonces la 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))
eso tiene que ser
create table VMS_AUDIT_RECORDS (id **bigint** not null auto_increment primary key (id))
Directamente al grano, 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.
Aquí está mi objeto 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 el método de persist
JPA EntityManager
.
Aquí hay un registro:
Hibernate: insert into Operator (active, password, username, id) values (?, ?, ?, ?)
com.mysql.jdbc.JDBC4PreparedStatement@15724a0: insert into Operator (active,password, username, id) values (0, ''pass'', ''user'', ** NOT SPECIFIED **)
La forma en que lo veo, el problema es la configuración con incremento automático, pero no puedo averiguar dónde.
Probé algunos trucos que he visto aquí: Hibernate no respeta el campo de clave primaria de auto_increment de MySQL Pero nada de eso funcionó
Si necesitan otros archivos de configuración, los 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`)
)
Intenté todo, pero aún así no pude hacer eso, estoy usando mysql, jpa con hibernate, resolví mi problema asignando el valor de id 0 en el constructor. A continuación está mi código de declaración de identificación.
@Id
@Column(name="id",updatable=false,nullable=false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Para cualquiera que lea esto y esté usando EclipseLink para JPA 2.0, aquí están 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 usan EclipseLink (y posiblemente otros proveedores JPA), es CRÍTICO que establezca el atributo allocationSize para que coincida con el valor INCREMENT 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. Aquí está 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 dar contexto, esto es lo que estamos usando:
Java 7 Glassfish 3.1 PostgreSQL 9.1 PrimeFaces 3.2 / JSF 2.1
Además, por 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 tratar con columnas de ID basadas en secuencias, por lo que deberás agregar manualmente estas anotaciones.
Para usar una columna AUTO_INCREMENT
MySQL, se supone que debes usar una estrategia de IDENTITY
:
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
Que es lo que obtendrías al usar 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, tu mapeo debería funcionar. Pero Hibernate debe omitir la columna id
en la declaración de inserción de 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
dependiendo del motor que esté utilizando)?
Además, ¿quién creó la mesa? ¿Puedes mostrar el DDL correspondiente?
Seguimiento: no puedo reproducir su problema. Usando el código de su entidad y su DDL, Hibernate genera el siguiente (esperado) SQL con MySQL:
insert
into
Operator
(active, password, username)
values
(?, ?, ?)
Tenga en cuenta que la columna de 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 al dialecto, la única diferencia entre MySQL5Dialect
o MySQL5InnoDBDialect
es que el último agrega ENGINE=InnoDB
a los objetos de la tabla al generar el DDL. El uso de uno u otro no cambia el SQL generado.
Usando MySQL, solo este enfoque me funcionaba a mí:
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
Los otros 2 enfoques planteados por Pascal en su respuesta no me funcionaron.