secuencia de oracle de hibernación produce una gran brecha

Estoy usando Hibernate 3, Oracle 10g. Tengo una mesa: sujeto. La definición está aquí

CREATE TABLE SUBJECT ( SUBJECT_ID NUMBER (10), FNAME VARCHAR2(30) not null, LNAME VARCHAR2(30) not null, EMAILADR VARCHAR2 (40), BIRTHDT DATE not null, constraint pk_sub primary key(subject_id) USING INDEX TABLESPACE data_index ) ; 

cuando insertas un nuevo asunto, sub_seq se usa para crear un id. de sujeto, la definición está aquí

 create sequence sub_seq MINVALUE 1 MAXVALUE 999999999999999999999999999 START WITH 1 INCREMENT BY 1 CACHE 100 NOCYCLE ; 

la clase Subject es así:

 @Entity @Table(name="ktbs.syn_subject") public class Subject { @Id @Column(name="subject_id") @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SUB_SEQ") @SequenceGenerator(name="SUB_SEQ", sequenceName = "SUB_SEQ") private long subjectId; private String fname; private String lname; private String emailadr; private Date birthdt; } 

en la tabla de materias, ha habido 4555 sujetos en la base de datos cargados por scripts plsql de excel y la sub_secuencia funcionó bien. los números de sujeto van desde 1-4555.

sin embargo, cuando agregué un tema de mi aplicación usando hibernación, el número de secuencia saltó a 255050. Después de varios días de funcionamiento, los ID de sujeto generados por hibernación se ven así.

 270079 270078 270077 270076 270075 270074 270073 270072 270071 270070 270069 270068 270067 270066 270065 270064 270063 270062 270061 270060 270059 270058 270057 270056 270055 270054 270053 270052 270051 270050 265057 265056 265055 265054 265053 265052 265051 265050 260059 260058 260057 260056 260055 260054 260053 260052 260051 260050 255067 255066 255065 255064 255063 255062 255061 255060 255059 255058 255057 255056 255055 255054 255053 255052 255051 255050 4555 4554 4553 . . . . 1 

Hay varias brechas grandes: 4555 a 255051, 255067 a 260051, 265057 a 270051

esto es un desperdicio y no un comportamiento deseado.

¿Alguien sabe por qué sucede esto y caliente para arreglarlo

Gracias

Creo que el problema proviene del hecho de que el generador de secuencia no es realmente un generador de secuencia, sino un generador de secuencia de secuencia, con un tamaño de asignación predeterminado de 50, como lo indica la documentación: http://docs.jboss.org/ hibernate / estable / anotaciones / reference / en / html_single / # entity-mapping-identifier

Esto significa que si el valor de secuencia es 5000, el siguiente valor generado será 5000 * 50 = 250000. Agregue el valor de caché de la secuencia a la ecuación, y podría explicar su gran brecha inicial.

Verifica el valor de la secuencia. Debe ser menor que el último identificador generado. Tenga cuidado de no reinicializar la secuencia a este último valor generado + 1, ya que el valor generado crecería exponencialmente (tuvimos este problema y tuvimos identificaciones de entero negativas debido a desbordamiento)

De acuerdo con JB. Pero aún así, gracias a PaulJ.

Para ser más específico a mi código de anotación a continuación:

 @Entity @Table(name="ktbs.syn_subject") public class Subject { @Id @Column(name="subject_id") @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SUB_SEQ") @javax.persistence.SequenceGenerator(name="SUB_SEQ", sequenceName = "SUB_SEQ") private long subjectId; private String fname; private String lname; private String emailadr; private Date birthdt; } 

Si usa javax.persistence.SequenceGenerator , hibernate use hilo y posiblemente creará grandes lagunas en la secuencia. Hay una publicación que aborda este problema: https://forum.hibernate.org/viewtopic.php?t=973682

Hay dos formas de solucionar este problema

  1. En la anotación SequenceGenerator, agregue allocationSize = 1, initialValue= 1
  2. en lugar de usar javax.persistence.SequenceGenerator, use org.hibernate.annotations, así:

     @javax.persistence.SequenceGenerator( name = "Question_id_sequence", sequenceName = "S_QUESTION" ) @org.hibernate.annotations.GenericGenerator( name="Question_id_sequence", strategy = "sequence", parameters = { @Parameter(name="sequence", value="S_QUESTION") } ) 

He probado ambas formas, lo cual funciona bien.

Otra solución es:

Use ‘strategy = GenerationType.AUTO’ en lugar de ‘strategy = GenerationType.SEQUENCE’, como se muestra a continuación

 @Id @SequenceGenerator(name = "studentId", sequenceName = "student_Id") @GeneratedValue(strategy = GenerationType.AUTO, generator="studentId") private int studentId; 

En realidad, tener allocationSize = 1 está bien si tu secuencia INCREMENT VALUE es 1 y no tienes la necesidad de persistir en muchas entidades. Sin embargo, si desea conservar miles o millones de registros , la configuración anterior podría convertirse en un cuello de botella de rendimiento, ya que cada vez que se guarde debe buscar un ID, por lo tanto, se necesita una lectura de base de datos.

Para resolver este problema, debemos establecer el allocationSize en algo así como 500 y secuenciar INCREMENT VALUE en DB también a 500, luego lo más importante agregar una configuración hibernate.id.new_generator_mappings para pedirle que use la nueva implementación del generador de secuencia, aquí supongamos que establece sus propiedades de hibernación en una clase de configuración de Java:

 properties.setProperty("hibernate.id.new_generator_mappings", Boolean.toString(true)); 

De esta forma, Hibernate usará SequenceStyleGenerator lugar del antiguo SequenceHiLoGenerator para generar los ids. SequenceStyleGenerator es más amigable para jpa y oracle. Genera valores de identificador basados ​​en una estructura de base de datos de estilo de secuencia. Las variaciones van desde usar una secuencia hasta usar una tabla para imitar una secuencia.

Mira mi publicación para más detalles si estás en el mismo barco:

vcfvct.wordpress.com/2016/04/23/jpa-sequencegenerator-with-allocationsize-1-performance-tuning/

Si lee el siguiente enlace, verá que el problema está causado por la configuración de CACHE en su comando de creación de secuencia. La eliminación de la configuración de caché resolverá el problema hasta cierto punto, pero no tiene en cuenta la posibilidad de retrocesos, etc.

El enlace es: http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:369390500346406705

La única forma de volver a sincronizar sus secuencias ahora es volver a crear la secuencia, cambiar el nombre de la tabla actual y crear la tabla de nuevo y luego volver a insertar los registros de la tabla anterior en la nueva tabla.

NOTA: El valor de caché para secuencias es útil para cargas grandes donde los valores de secuencia ‘x’ se asignan a la vez. Si está utilizando un sistema de transacciones en el que realiza una inserción a la vez, entonces el almacenamiento en caché no es útil (o debo decir, nunca lo he encontrado útil).

NOTA: Esta es mi comprensión de la opción de caché para secuencias. Puede buscar Oracle Documentation en los comandos CREATE SEQUENCE para obtener más información. Pero el enlace de arriba debe proporcionar una respuesta razonable a su pregunta.

Gracias. Pablo

La respuesta más exitosa sería:

 @Id @SequenceGenerator (name = "id_sequence", sequenceName = "sq50") @GeneratedValue(strategy = GenerationType.AUTO, generator = "id_sequence") public int getId() { return id; } 

Tuve problemas similares generador de secuencia y generador de secuencia de secuencia son bastante similares pero tienen diferencias. En hibernate 3, el generador de hilo se multiplica por el valor predeterminado 50. Por lo tanto, no es necesario incrementar la secuencia DB. Por otro lado, las versiones posteriores de hibernate usan un generador de secuencia por defecto. Por lo tanto, se requiere un incremento de DB de 50.

https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6.3/html/Migration_Guide/Preserve_the_Existing_Behavior_of_the_Hibernate_Identity_Auto_Generated_Value1.html

Tuve este problema que tienen múltiples versiones de hibernación (3 y 5). La misma configuración funcionó bien (incrementó en 1 en DB). Pero falló en Hibernate 5. Por lo tanto, actualizo mi persistence.xml como se muestra a continuación. Esto asegura la generación de la cuerda

   

Como se dijo aquí , intente ajustar su SequenceGenerator.allocationSize con su secuencia de la base de datos INCREMENT BY number.

Una solución a esto podemos configurar el generador de secuencias con allocationSize como:

 @SequenceGenerator(name = "gen_name", sequenceName = "seq_name", allocationSize= 1) 
Intereting Posts