El uso hibernado de la secuencia de PostgreSQL no afecta a la tabla de secuencias


He configurado Hibernate para usar la secuencia de PostgreSQL (a través de anotaciones) para generar valores para la columna clave primaria id 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 id valores > 3000 al persistir, mientras que la consulta sobre la secuencia utilizada muestra lo siguiente:

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

(1 fila)

Preguntas:
¿Hay algo malo o no?
¿Debería hibernar la sincronización con la tabla de secuencias?
Si no, donde ¿almacena el último ID generado?

Gracias.

Author: forker, 2010-11-27

4 answers

Yo tenía el mismo problema. Está relacionado con las estrategias de asignación de id de Hibernate. Cuando elija GenerationType.SEQUENCE , Hibernate utiliza la estrategia HiLo que asigna IDs en bloques de 50 por defecto. Así que puede establecer explícitamente allocationSize valor 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 usar la estrategia HiLo con allocationSize=1 no es una buena práctica. Algunas personas recomiendan usar GenerationType.AUTO en su lugar cuando tener que lidiar con secuencias administradas por bases 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 IDs de todos modos, así que YMMV.

 28
Author: Nofate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-03 22:04:45

NO UTILICE GenerationType.SECUENCIA para Postgres secuencias!

Es completamente contrario a la intuición, pero la gente de Hibernación se equivocó completamente en esto. debe usar GenerationType.AUTO o Hibernate demolerán sus secuencias si tiene que reiniciar/reconstruir su base de datos. Es casi criminalmente negligente que permitieran que este código entrara en una compilación de producción, pero el equipo de Hibernación es bastante famoso por sus posturas torcidas hacia posiciones totalmente erróneas (por ejemplo, echa un vistazo a su posición en las uniones a la IZQUIERDA).

 23
Author: Matt Brock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-21 17:21:33

Primero, debe determinar qué versión de Hibernate está utilizando. En términos de las versiones hibernate-core, la 3.2 en adelante introdujo un soporte más consistente para los generadores de id, especialmente en lo que respecta a los definidos en las anotaciones. Véase 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 las anotaciones JPA son manejar. La configuración es false por defecto porque Hibernate tiene que mantener la compatibilidad con versiones anteriores. Si desea el nuevo comportamiento (que es completamente recomendado), simplemente establezca ese ajuste en true.

Cómo se maneja GenerationType depende de la versión que esté utilizando y si tiene 'hibernate.id.new_generator_mappings' establecido en true. Voy a suponer que usted está usando 3.6+ (ya que nada más es, pues, el viejo) y no tener 'hibernación.id.new_generator_mappings' establecer en true (ya que es la recomendación para nuevas aplicaciones):

  1. GenerationType.AUTO - > tratado como GenerationType.SECUENCIA
  2. GenerationType.SEQUENCE - > se asigna a la clase org.hibernate.id.enhanced.SequenceStyleGenerator discutida en el blog
  3. GenerationType.TABLE - > mapea la clase org.hibernate.id.enhanced.TableGenerator discutida en el blog
 7
Author: Steve Ebersole,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-05 20:36:06

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;

En su mayoría con nombres en mayúsculas Hibernate es necesario pasar comillas escapadas con el fin de entender Postgres y encontrar los nombres de tablas, columnas o secuencias.

 0
Author: Christian Vielma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-03 15:43:09