El uso de Hibernate de la secuencia PostgreSQL no afecta la tabla de secuencias

He configurado Hibernate para utilizar la secuencia de PostgreSQL (a través de anotaciones) para generar valores para la columna de identificación de clave principal de la siguiente manera:

@Id @SequenceGenerator(name="pk_sequence",sequenceName="entity_id_seq") @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="pk_sequence") @Column(name="id", unique=true, nullable=false) public int getId() { return this.id; } 

Lo que veo con esta configuración es que hibernate ya está asignando valores de id > 3000 en la persistencia, mientras que la consulta en la secuencia utilizada muestra lo siguiente:

 database=# select last_value from entity_id_seq; last_value ------------ 69 

(1 fila)

Preguntas:
¿Hay algo mal o no?
¿Debería hibernate la sincronización con la tabla de secuencias?
Si no, ¿dónde almacena la última identificación generada?

Gracias.

Yo tuve el mismo problema. Está relacionado con las estrategias de asignación de id de Hibernate. Cuando elige GenerationType.SEQUENCE , Hibernate usa la estrategia HiLo, que asigna identificaciones en bloques de 50 de forma predeterminada. Para que pueda establecer explícitamente un valor de allocationSize como este:

 @Id @SequenceGenerator(name="pk_sequence",sequenceName="entity_id_seq", allocationSize=1) @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="pk_sequence") @Column(name="id", unique=true, nullable=false) public int getId() { return this.id; } 

Sin embargo, también he escuchado opiniones de que el uso de la estrategia HiLo con allocationSize = 1 no es una buena práctica. Algunas personas recomiendan usar GenerationType.AUTO en su lugar cuando tienes que lidiar con secuencias administradas por la base de datos

Actualización: terminé yendo con allocationSize = 1, y las cosas parecen funcionar como espero ahora. Mi aplicación es tal que realmente no necesito bloques de ID de todos modos, entonces YMMV .

¡NO USE GenerationType.SEQUENCE para las secuencias de Postgres!

Es completamente contra-intuitivo, pero la gente de Hibernate se equivocó completamente en esto. Debe usar GenerationType.AUTO o Hibernate demolerá sus secuencias si tiene que reiniciar / reconstruir su base de datos. Es casi criminalmente negligente que permitan que este código entre en producción, pero el equipo de Hibernate es bastante famoso por sus posturas taimadas hacia posiciones completamente erróneas (verifique su posición en LEFT JOINs, por ejemplo).

En primer lugar, debe determinar qué versión de Hibernate está utilizando. En términos de versiones hibernate-core, 3.2 en adelante introdujo un soporte más consistente para los generadores de id especialmente en lo que respecta a lo definido en las anotaciones. Ver http://in.relation.to/Bloggers/New323HibernateIdentifierGenerators para una discusión.

Next 3.6 introdujo una configuración (‘hibernate.id.new_generator_mappings’) que hace que los generadores discutidos en ese blog sean la forma predeterminada en que se manejan las anotaciones JPA. La configuración es falsa de forma predeterminada porque Hibernate tiene que mantener la compatibilidad con versiones anteriores. Si desea el nuevo comportamiento (que se recomienda por completo), simplemente configure esa configuración en verdadero.

El modo en que se maneja GenerationType depende de la versión que esté utilizando y de si tiene ‘hibernate.id.new_generator_mappings’ establecido en verdadero. Asumiré que estás usando 3.6+ (ya que cualquier cosa anterior es, bueno, viejo) y tienes ‘hibernate.id.new_generator_mappings’ establecido en verdadero (ya que esa es la recomendación para nuevas aplicaciones):

  1. GenerationType.AUTO -> tratado como GenerationType.SEQUENCE
  2. GenerationType.SEQUENCE -> se asigna a la clase org.hibernate.id.enhanced.SequenceStyleGenerator discutida en el blog
  3. GenerationType.TABLE -> se asigna a la clase org.hibernate.id.enhanced.TableGenerator discutida en el blog

En Postgres, haría esto:

 @Id @SequenceGenerator(name="pk_sequence",sequenceName="\"entity_id_seq\"") @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="\"pk_sequence\"") @Column(name="\"id\"", unique=true) private int id; 

Sobre todo con nombres en mayúsculas, Hibernate necesita pasar citas escapadas para entender Postgres y encontrar las tablas, columnas o nombres de secuencias.