Los identificadores para entidades JPA (@Id mapeados como Primary Keys) pueden ser identificadores naturales con algún tipo de significado para la aplicación (NIF, email, etc…) o generados por el sistema y automáticamente asignados al objeto (normalmente utilizando la anotación @GeneratedValue).
Hasta aquí nada nuevo, pero ahora vamos a repasar las diferentes estratégias disponibles:
Secuencia basada en TABLA
En esta estrategia hacemos uso de una tabla auxiliar con la que gestionar los identificadores secuenciales. En la tabla aparecerá una nueva fila por cada objeto de secuencia y cada ver que se necesite un nuevo identificador se incrementará la secuenca almacenada en la tabla y asignará dicho identificador.
Este mecanismo es uno de los más portables y es recomendable en casos de que deseemos maximizar la portabilidad de nuestra aplicación.
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
public Long id;
En cuanto a rendimiento, esta solución ofrece un buen rendimiento ya que permite reservar grupos de identificadores de forma que se minimicen los accesos a dicha tabla y el comportamiento es muy bueno ya que permite conocer los identificadores sin necesidad de realizar el commit.
El único problema que plantea es que en determinadas ocasiones puede causar bloqueos. En concreto en las situaciones en las que el propio acceso a la tabla de secuencias se realice de forma transaccional y podamos tener otros procesos a su vez consumiendo dicha tabla. Por este motivo esta solución no es recomendable a no ser que se utilicen conexiones no-JTA para el acceso a la tabla de secuencias.
Identit
Esta estratégia de generación hace uso de un tipo de columna especial IDENTITY que está disponile en la mayoría de las bases de datos (desgraciadamente no está disponible en ORACLE).
Respecto a la portabilidad, este método de generación es portable ya a pesar de no estar disponible en Oracle puede ser facilmente simulado mediante trigers. Ofreciendo de una forma muy sencilla su potabilidad en el resto de bases de datos.
A pesar de ser un mecanismo muy utilizado, el principal problema de este mecanismo es su que no resulta nada eficiente, ya que dado que es la base de datos la que se encarga de autogenerar el valor, necesitaremos hacer un segundo acceso (en lectura) para conocer el identificador asignado. Al no poder realizar pre reserva de identificadores, este método es muy ineficiente y en general no recomendable.
Objeto de Secuencia
En este caso se hace uso de un tipo de recurso específico de las base de datos dedicado a la generación de secuenciaS. El principal problema que plantéa este método es que no está disponible en todas las bases de datos por lo que el código puede puede resultar no portable.
En cuento a rendimiento, ofrece una solución optima ya que permite definir bloques de identificadores reservados, de forma que se minimicen los accesos a la secuencia.
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
public Long id;
Y aunque todos estos conceptos son relativamente conocidos por los que asiduamente utilizan JPA, hay que tenerlos muy encuesta si necesitas que su aplicación funcione sin problemas por ejemplo en SQL Server, PostgreSQL, Oracle y Mysql!