2009-11-30 35 views
10

mi mirada entidad clave principal, como a continuaciónAPP primaria de auto clave generar

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

cuando corro, me sale error

No se pudo obtener o actualizar el valor siguiente; la excepción anidada es org.hibernate.exception. SQLGrammerException: no se pudo obtener o actualizar siguiente valor

pero cuando acabo de cambiar a

@GeneratedValue 
private Long id; 

sin error. Deseo generar clave primaria única por tabla en oracle db.

Respuesta

28

El @GeneratedValue(strategy=GenerationType.TABLE) le dice al proveedor de JPA que use una tabla para obtener ID al insertar entidades recién creadas en la base de datos.

Al usar Hibernate como proveedor, esto dará como resultado una tabla hibernate_sequences que tiene dos columnas: el nombre de la entidad y la identidad máxima ya asignada a esta entidad. Aquí, parece que Hibernate no consigue obtener el siguiente ID de su entidad, pero es difícil decir exactamente por qué porque no proporcionó suficiente información para eso.

Entonces, ¿podría por favor proporcionar la stacktrace completa? Además, active el registro con la propiedad hibernate.show_sql establecida en true y configure el nivel de registro adecuado log4j.logger.org.hibernate.SQL=DEBUG. Únase al registro de su pregunta si es posible.

Tal vez solo verifique que configuró el hibernate.dialect correcto para Oracle. En realidad, únete a tu configuración de hibernación también si es posible.

PD: La forma "tradicional" de generar PK con Oracle es usar secuencias (puede dejar que Hibernate adivine la mejor estrategia para su tipo de base de datos usando GenerationType.AUTO o forzarlo usando SEQUENCE) pero supongo que quiere la resultante la estructura de datos debe ser independiente de la base de datos. Si no, sugeriría ir a las secuencias en su lugar.

EDIT: respondiendo un comentario de la OP sobre GenerationType.AUTO. De hecho, el valor predeterminado es una secuencia global única llamada hibernate_sequence y esto podría ser un problema. Sin embargo, con la configuración se muestra a continuación, puede utilizar GenerationType.AUTO y todavía controlar el nombre de la secuencia para los casos en que la base de datos utiliza secuencias:

@Id 
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_entity_seq_gen") 
@SequenceGenerator(name="my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ") 
private long id; 

En otras palabras, se puede utilizar utilizar un nombre de secuencia diferente para cada mesa sin perder la portabilidad.

+2

si pongo GenerationType.Auto, utilizará el número incremental global, significa que todas mis entidades incrementarán el mismo número. El código funciona bien, pero ¿se quedará sin número incremental? – cometta

+0

@Pascal: Si proporcionamos un SequenceGenerator ¿ayuda a especificar la estrategia como AUTO? – Nrj

+0

@Nrj En realidad, si usa 'AUTO' y si la base de datos usa secuencias,' @ SequenceGenerator' ayudará a controlar el nombre de la secuencia. Pero simplemente será "ignorado" si la base de datos no lo hace (por ejemplo, con HSQLDB). Entonces, a diferencia de 'SEQUENCE', esto sigue siendo portátil. –

7

Hay 4 estrategias para la generación automática de la APP:

  • Auto
  • Identidad
  • Secuencia
  • Tabla

Para Oracle generación automática de clave primaria de anotación, la secuencia y la tabla son tus eleccionesLa lógica básica es definir primero un generador, usar @SequenceGenerator o @ TableGenerator respectivamente, luego usar el generador como atributo en @GeneratedValue.

Este es un ejemplo de cómo utilizar la estrategia de secuencia:

@Id 
    @SequenceGenerator(name="SEQ_GEN", sequenceName="SEQ_JUST_FOR_TEST", allocationSize=1) 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_GEN") 
    private long id; 

Aquí es un ejemplo de cómo utilizar la estrategia tabla:

@Id 
    @TableGenerator(name="TABLE_GEN",table="T_GENERATOR", pkColumnName = "GEN_KEY", pkColumnValue = "MONITOR2012.T_JUST_FOR_TEST", valueColumnName = "GEN_VALUE", initialValue = 1, allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.TABLE, generator="TABLE_GEN") 
    private long id; 

Si ningún generador especifica en @GeneratedValue anotación , la elección saldrá a la implementación de JPA.

Si está trabajando en una base de datos con tablas existentes, asegúrese de tener la secuencia o la tabla definida en la base de datos antes de ejecutar la aplicación. El generador de tablas también necesitará que inserte una línea en la tabla antes de que la anotación @GeneratedValue funcione correctamente.

Aquí hay un tutorial sobre how to configure primary key auto generation in JPA for Oracle database.

Cuestiones relacionadas