java - llave - secuencias en jpa
Cómo elegir la estrategia de generación de id cuando utilizas JPA e Hibernate (4)
Básicamente, tienes dos opciones principales:
- Puede generar el identificador usted mismo, en cuyo caso puede usar un identificador asignado .
- Puede usar la anotación
@GeneratedValue
e Hibernate le asignará el identificador.
Para los identificadores generados tiene dos opciones:
- Identificadores UUID .
- Identificadores numéricos
Para los identificadores numéricos , tiene tres opciones :
- IDENTIDAD
- SECUENCIA
- MESA
IDENTIDAD es solo una buena opción cuando no puede usar SEQUENCE (por ejemplo, MySQL) porque deshabilita las actualizaciones por lotes de JDBC .
SECUENCIA es la opción preferida, especialmente cuando se usa con un optimizador de identificador como agrupado o agrupado-lo .
TABLE debe evitarse a toda costa, ya que utiliza una transacción por separado para obtener el identificador y los bloqueos a nivel de fila que escalan mal.
Estaba pasando por la sección de generación de Id de la guía de referencia de Hibernate y "la persistencia de Java con Hibernate"
Hay bastantes opciones disponibles con Hibernate y JPA combinados.
Estaba buscando otra documentación sobre cómo elegir la estrategia de generación de identificador específica.
También estoy buscando puntos de inflexión.
Por ejemplo, se espera que la estrategia del hilo reduzca la contención. Estoy asumiendo que debe haber una compensación asociada con esta elección.
Quiero ser educado sobre las compensaciones.
¿Hay literatura disponible?
El API Doc es muy claro en esto.
Todos los generadores implementan la interfaz org.hibernate.id.IdentifierGenerator. Esta es una interfaz muy simple. Algunas aplicaciones pueden optar por proporcionar sus propias implementaciones especializadas, sin embargo, Hibernate proporciona una gama de implementaciones integradas. Los nombres de acceso directo para los generadores incorporados son los siguientes:
incremento
genera identificadores de tipo long, short o int que son únicos solo cuando ningún otro proceso está insertando datos en la misma tabla. No usar en un clúster
identidad
admite columnas de identidad en DB2, MySQL, MS SQL Server, Sybase e HypersonicSQL. El identificador devuelto es de tipo long, short o int.
secuencia
utiliza una secuencia en DB2, PostgreSQL, Oracle, SAP DB, McKoi o un generador en Interbase. El identificador devuelto es de tipo long, short o int
hilo
utiliza un algoritmo hi / lo para generar de manera eficiente identificadores de tipo long, short o int, dada una tabla y columna (por defecto hibernate_unique_key y next_hi respectivamente) como fuente de valores hi. El algoritmo hi / lo genera identificadores que son únicos solo para una base de datos particular.
seqhilo
utiliza un algoritmo hi / lo para generar de manera eficiente identificadores de tipo long, short o int, dada una secuencia de base de datos con nombre.
uuid
utiliza un algoritmo UUID de 128 bits para generar identificadores de tipo cadena que son únicos dentro de una red (se usa la dirección IP). El UUID está codificado como una cadena de 32 dígitos hexadecimales de longitud.
guid
utiliza una cadena GUID generada en la base de datos en MS SQL Server y MySQL.
nativo
selecciona identidad, secuencia o hilo dependiendo de las capacidades de la base de datos subyacente.
asignado
permite que la aplicación asigne un identificador al objeto antes de llamar a save (). Esta es la estrategia predeterminada si no se especifica ningún elemento.
seleccionar
recupera una clave principal, asignada por un activador de base de datos, seleccionando la fila mediante una clave única y recuperando el valor de la clave primaria.
exterior
usa el identificador de otro objeto asociado. Por lo general, se usa junto con una asociación de clave primaria.
secuencia-identidad
una estrategia de generación de secuencia especializada que utiliza una secuencia de base de datos para la generación de valor real, pero la combina con JDBC3 getGeneratedKeys para devolver el valor del identificador generado como parte de la ejecución de la instrucción de inserción. Esta estrategia solo se admite en los controladores Oracle 10g para JDK 1.4. Los comentarios sobre estas declaraciones de inserción están deshabilitados debido a un error en los controladores de Oracle.
Si está compilando una aplicación simple con pocos usuarios concurrentes, puede ir por increment, identity, hilo, etc. Estos son simples de configurar y no necesitan mucha codificación dentro de la base de datos.
Debe elegir la secuencia o guid dependiendo de su base de datos. Estos son seguros y mejores porque la generación de id
ocurrirá dentro de la base de datos.
Actualización: Recientemente tuvimos un problema con idendity donde primitive type (int) esto se solucionó usando warapper type (Integer) en su lugar.
Encuentro esta conferencia muy valiosa https://vimeo.com/190275665 , en el punto 3 se resumen estos generadores y también da algunos análisis de rendimiento y la pauta uno cuando se usa cada uno.
Hace un tiempo escribí un artículo detallado sobre los generadores de llaves Hibernate: http://blog.eyallupu.com/2011/01/hibernatejpa-identity-generators.html
Elegir el generador correcto es una tarea complicada, pero es importante tratar de hacerlo bien lo antes posible; una migración tardía puede ser una pesadilla.
Un poco fuera del tema, pero una buena oportunidad para plantear un punto por lo general pasado por alto, que es compartir claves entre las aplicaciones (a través de API). Personalmente, siempre prefiero las claves sustitutas y, si necesito comunicar mis objetos con otros sistemas, no expongo mi clave (aunque sea sustituta). Utilizo una "clave externa" adicional. Como consultor, he visto más de una vez ''grandes'' integraciones de sistemas usando claves de objetos (el enfoque ''es ahí vamos a usarlo'') solo para encontrar un año o dos después que un lado tiene problemas con el rango de teclas o algo así el tipo que requiere una migración profunda en el sistema exponiendo sus claves internas. Exponer su clave significa exponer un aspecto fundamental de su código a restricciones externas que realmente no deberían exponerse.