Todos conocemos el comportamiento predeterminado de Hibernate al usarlo @SequenceGenerator
: aumenta la secuencia de la base de datos real en uno , multiplica este valor por 50 ( allocationSize
valor predeterminado ) y luego usa este valor como ID de entidad.
Este es un comportamiento incorrecto y entra en conflicto con la especificación que dice:
LocationSize - (Opcional) La cantidad a incrementar cuando se asignan números de secuencia de la secuencia.
Para ser claros: no me preocupo por las brechas entre los ID generados.
Me preocupan las identificaciones que no son consistentes con la secuencia de la base de datos subyacente. Por ejemplo: cualquier otra aplicación (que, por ejemplo, use JDBC simple) puede querer insertar nuevas filas bajo los ID obtenidos de la secuencia, ¡pero Hibernate ya puede usar todos esos valores! Locura.
¿Alguien conoce alguna solución a este problema (sin configurar allocationSize=1
y, por lo tanto, degradar el rendimiento)?
EDITAR:
Para aclarar las cosas. Si el último registro insertado tenía ID = 1
, entonces HB usa valores 51, 52, 53...
para sus nuevas entidades PERO al mismo tiempo: el valor de la secuencia en la base de datos se establecerá en 2
. Lo que puede conducir fácilmente a errores cuando otras aplicaciones utilizan esa secuencia.
Por otro lado: la especificación dice (según tengo entendido) que la secuencia de la base de datos debería haberse configurado 51
y, mientras tanto, HB debería usar valores del rango 2, 3 ... 50
ACTUALIZACIÓN:
Como Steve Ebersole mencionó a continuación: el comportamiento descrito por mí (y también el más intuitivo para muchos) se puede habilitar configurando hibernate.id.new_generator_mappings=true
.
Gracias a todos.
ACTUALIZACIÓN 2:
Para futuros lectores, a continuación puede encontrar un ejemplo práctico.
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERS_SEQ")
@SequenceGenerator(name = "USERS_SEQ", sequenceName = "SEQUENCE_USERS")
private Long id;
}
persistence.xml
<persistence-unit name="testPU">
<properties>
<property name="hibernate.id.new_generator_mappings" value="true" />
</properties>
</persistence-unit>
save
necesitan consultar la base de datos para el siguiente valor de la secuencia.
SequenceGenerator
Hibernate consultará la base de datos solo cuando se allocationsize
agote la cantidad de ID especificados por . Si lo configura, allocationSize = 1
entonces es la razón por la que Hibernate consulta la base de datos para cada inserción. Cambie este valor y listo.
hibernate.id.new_generator_mappings
entorno es realmente importante. Espero que sea la configuración predeterminada que no tenga que dedicar tanto tiempo a investigar por qué el número de identificación se vuelve loco.