2012-03-25 31 views
15

tengo una clase con la siguiente definición:Hibernate genera valores de id negativos cuando se utiliza una secuencia

@Id 
@SequenceGenerator(name = "SEQ_ACE_WORKERS_QUEUE_STATS_ID", sequenceName = "SEQ_ACE_WORKERS_QUEUE_STATS_ID", allocationSize = 500) 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ACE_WORKERS_QUEUE_STATS_ID") 
@Column(name = "ID") 
private long Id; 

Cuando nos encontramos en Jboss 4.2.3 funcionó bien y generó de la identificación apropiada (a partir de 1000)

Ahora nos movemos a jboss 7.1.1 y genera identificaciones negativas! (a partir de -498 y subiendo)

¿Alguna idea de por qué esto podría pasar?

+1

¿comprobó cuál es la secuencia actual en Oracle y rastreó la salida de hibernación, si ve la secuencia de selección adecuada siguiente consulta y si copia pegar en sqlplus obtiene el resultado correcto/mismo/esperado? – HRgiger

Respuesta

24

Acabo de toparme con este problema al migrar de JBoss 6.1 a JBoss 7.1.

Según el JBoss AS 7.1 documentación JPA (https://docs.jboss.org/author/display/AS71/JPA+Reference+Guide#JPAReferenceGuide-Persistenceunitproperties),

JBoss 7.1 establece automáticamente varias propiedades de hibernación. Una de las propiedades configuradas es hibernate.id.new_generator_mappings que activa nuevos generadores de ID que utilizan diferentes algoritmos y que no son compatibles con versiones anteriores. Establecer esta propiedad en falso en su archivo persistence.xml restaurará el comportamiento del generador de ID anterior.

La documentación de hibernación 4 también contiene información sobre los nuevos generadores de ID: http://docs.jboss.org/hibernate/core/4.0/manual/en-US/html_single/#mapping-declaration-id-generator.

La documentación de hibernación establece claramente que los nuevos generadores de ID no están habilitados por defecto, pero, como se indicó anteriormente, JBoss 7.1 los habilita automáticamente.

+0

Gracias por la respuesta, ya logré encontrarlo, olvidé actualizarlo aquí :( – Tomer

+0

Comenzando con la versión 5.0 de Hibernate, la propiedad 'hibernate.id.new_generator_mappings' se establece por defecto en' true'. Ver http: //docs.jboss .org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html # identificadores-generadores –

12

Configuración hibernate.id.new_generator_mappings a false en mi persistence.xml fue sólo la primera parte de la solución a mi problema:

Para resolver completamente el problema he añadido el allocationSize a 1 en el @SequenceGenerator (que estaba omitiendo).

30

El nuevo comportamiento es lo siguiente:

allocationSize es una gama de valores de clave principal reservadas para Hibernate. Y la selección seq.nextval de dual se realizará solo después de que hibernate haya consumido este rango de teclas principales.

Así que debe declarar el mismo valor en ambas allocationSize (Hibernate) y la secuencia increment by (DB)

Cuando se establece explícitamente allocationSize=500, por ejemplo, en Oracle

create sequence SEQ_ACE_WORKERS_QUEUE_STATS_ID 
     MINVALUE 1 
     MAXVALUE 999999999999999999999999999 
     START WITH 1 
     INCREMENT BY 500 
     NOCACHE 
     NOCYCLE; 

De lo contrario, se dará cuenta de valores negativos o errores de restricción obtenidos de su base de datos debido a las colisiones de clave principal.

Cuando se reinicia el servidor de aplicaciones, notará el "salto" entre la última clave principal asignada y el "nuevo" número de secuencia seleccionado al reiniciar.

comentario final: valor por defecto es 50. Así que si no se especifica allocationSize en el lado de hibernación, que debe declararincrement by 50 en el lado DB.

+0

Respuesta muy útil, ya que esta información aparentemente no está en los documentos de Hibernate. –

Cuestiones relacionadas