Mapear Tablas a Entities

=Introducción=

El Eclipse junto con Apache nos ofrecen herramientas para mapear tablas a entities, uno de los conceptos principales del estándar JPA. Describiremos en este documento cómo utilizar esta funcionalidad, para facilitar el mapeo. Sugerimos la creación de otro proyecto, en base a experiencias previas, debido a que una vez que un sistema está en producción, no es recomendable generar clases con asistentes (wizzards) sobre el código, y puede ser más prudente hacerlo en otro proyecto y mover las clases o sacar las diferencias entre los Entities generados y los que estén en producción.

=Creando un Proyecto JPA=

Desde el Eclipse, utilizando el asistente, crear un proyecto de tipo JPA (New => Project => JPA Project)

Aparecerá la ventana de New JPA Project

En Project name, colocar el nombre del proyecto

Luego en la sección Target runtime => Seleccionar la opción Apache Tomcat v8.0 o Apache Tomcat v8.5 dependiendo de la versión que esté utilizando.

Luego click en Next, aparecerá la ventana donde se debe elegir el source folder => Click en Next nuevamente.

Alternativa: Si Ud. ya posee un proyecto y quiere utilizar esta funcionalidad en él, puede agregar al proyecto el facet "JPA". Project -> Properties -> Project Facets -> JPA

Gracias a Reinaldo de Carvalho por el tip

Configurar por primera vez
En la ventana de JPA Facet o Data Source Explorer se debe configurar al menos una librería, y podemos descargarla directamente desde el IDE. Para eso, presionamos el botón Donwload Library ...



Se elige la versión más actual de la lista y luego click en Next



Se aceptan los términos de la licencia y se espera a que culmine la descarga. En caso exitoso se debería tener una configuración parecida a esta:



Definiendo la conexión
Asumiendo que la configuración fue exitosa, el siguiente paso es configurar la conexión, para ello hacer click en Add connection ... Y filtrar la búsqueda por PostgreSQL, seleccionar y más abajo colocar el nombre, por convención se recomienda llamarlo de la misma forma del hostname o IP del servidor. A modo de ejemplo lo llamaremos como: postgres-devel.



Luego click en Next

Aparecerá la ventana donde debemos especificar el driver, para ello hacer click en el botón New Driver Definition



Aparecerá la ventana donde vamos a seleccionar el template del driver(Ver imagen) Observación: Debe seleccionarlo para tener habilitada las demás opciones en la siguiente ventana



Luego ir a la pestaña JAR List click en Add JAR/Zip y allí buscar la ruta del .jar del postgres. (Eliminar el .jar que tiene por defecto ésta ventana)

Si utiliza Maven, el .jar estará disponible en el directorio correspondiente al repositorio, caso contrario deberá descargar la versión 9.1 para JDBC4, para más información y/o descarga Ir a Download Driver



Una vez que tenemos la ruta del driver para el postgres click en OK

Aparecerá la ventana para la configuración de Detalles de la Conexión

Allí colocar el nombre de la base de datos postgres, la URL, el usuario y password de conexión.



Luego hacer click en el botón Test Connection. Si la conexión fue exitosa debería salir éste mensaje



Click en el botón Finish

Y nuevamente click en el botón Finish para salir del JPA Facet.

Aparecerá la siguiente ventana, que lo único que hace es sugerir la perspectiva más adecuada para el proyecto que hemos creado, en éste caso un JPA Project. Basta con presionar click en Yes



=Mapeando las tablas=

Para lograr el mapeo debemos situarnos sobre el proyecto recientemente creado (En nuestro ejemplo generador entities), click derecho => JPA Tools => Generate entities from tables...

Nos traerá la ventana que muestra por Schemas las tablas disponibles, seleccionar el esquema y tablas que desee mapear. Para nuestro ejemplo elegimos el schema de Joko-Security con todas sus tablas.

Seleccionando el esquema y las tablas
Observación: Para seleccionar todas las tablas de una vez hacer click en el botón Select All



Click en el botón Next y aparecerá la ventana de asociación de las tablas como se muestra en la imagen



Aqui podemos realizar cambios si asi se desee haciendo click sobre cada asociación.

Luego hacer click en Next

Elegir generador de PK y paquete para los entities
Aparecerá la ventana de Default Entity Generation en la sección de Table mapping => Key generator => Elegir la opción Sequence Nótese que siguiendo las convenciones de la BD sugeridas, se puede utilizar los patterns $TABLE_$PK_SEQ para generar las anotaciones necesarias para que el JPA utilice la secuencia de la base de datos para los inserts.

También es necesario agregar estas propiedades al annotation @SequenceGenerator initialValue = 1, allocationSize = 1 Esto asegura que se tome de a uno los valores de la secuencia.

En la sección Domain java class => Package => Escribir el nombre del paquete, para nuestro ejemplo sería: opt.ticpy.mbohape.domain, aquí se estarán mapeando todas las tablas a entities

Por último click en el botón Finish



Si todo nos fue bien, entonces se tuvieron que haber mapeado las tablas a entities, como muestra la imagen de ejemplo.

Un ejemplo de las anotaciones para una secuencia correcta es:

@Id @SequenceGenerator(name="AUDIT_SESSION_ID_GENERATOR", sequenceName="AUDIT_SESSION_ID_SEQ") @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="AUDIT_SESSION_ID_GENERATOR") private Long id;



Para tener en cuenta: Si generamos mapeos de tablas que no forman parte del esquema default del usuario de base de datos con que se ejecutará el sistema, se puede utilizar la pestaña JPA Details que nos brinda el Eclipse. Que agregará la notación @Table seguido de otros datos necesarios para mapear al esquema seleccionado. Se recomienda anteponer el nombre del schema como se muestra en la parte seleccionada de la imagen más abajo.

Secuencias en Hibernate 5
Según la deprecated-list de la versión 5.0 de Hibernate, ha deprecado el uso de la anotación @SequenceGenerator.

org.hibernate.id.SequenceGenerator Use SequenceStyleGenerator instead

Se debe reemplazar dicha anotación por: @GenericGenerator, y este es un ejemplo de como utilizarla

@GenericGenerator(        name = "userSequenceGenerator",         strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",         parameters = {                 @Parameter(name = "schema", value = "profile"),                 @Parameter(name = "sequence_name", value = "user_id_seq"),                 @Parameter(name = "initial_value", value = "99999"),                 @Parameter(name = "increment_size", value = "1")         } ) @Id @GeneratedValue(generator = "userSequenceGenerator") @Basic(optional = false) @Column(name = "user_id") @NotNull private Long user_id;

Migración de Hibernate 4 al 5
Para las aplicaciones que ya cuenten con entities previamente creados, Hibernate ofrece la opción de agregar el siguiente parámetro para indicar que se debe utilizar el nuevo generador de secuencias: hibernate.id.new_generator_mappings=true