jueves, 30 de julio de 2015

Mapeo complejo JPA de tablas relacionadas - III

EXPLICACIÓN DEL MAPEO JPA

Para empezar, decir que es conveniente la anotación @table (name="") porque así nuestras entities pueden tener diferente nombre que las tablas. Soy partidario de esta práctica anotación.
Las columnas han sido mapeadas de la forma habitual, con @Column. Cuando el nombre del atributo de la clase java coincide con el nombre de la columna de la tabla mapeada no es necesario utilizar la etiqueta column. Sin embargo, considero muy útil y conveniente poner siempre el name de la columna mapeada, ya que nos permite modificar en el futuro el atributo sin ocasionar problemas con la base de datos.
Las clases han mapeado el @Id con strategy Identity. Ello es debido a que las tablas se han mapeado con la propiedad AutoIncrement; con esa anotación las tablas gestionan por ellas mismas el valor del id, liberándonos de esa tarea. Los ids han sido creados como long, cuyo equivalente en mysql es BigInt.
El trabajo verdaderamente importante es el mapeo de las relaciones entre las tablas. Como hemos definido antes, el objeto "empleado" está mapeado en dos tablas en las bases de datos, "empleados" y "datosprofesionales". Por lo tanto, ambas tablas deberán estar unidas en una relación @OneToOne bilateral.
Recordemos que, en la relación @OneToOne bilateral establece una relación en la cual cada objeto de una clase tiene relación con uno y solo un objeto de la otra clase, y viceversa. Una de las clases es "dueña" de la relación, lo cual significa que esa clase tendrá una referencia (la id) de la otra clase. Y esa referencia será mapeada en la tabla, en una columna que se añadirá. En la otra clase, la "referenciada", no añadirá ninguna columna a la tabla, pero el objeto tendrá referencia al objeto de la clase "dueña".
El mapeo de las referencias de las otras clases consiste en crear una propiedad del tipo de la clase mapeada, la cual empleará JPA para obtener la referencia id de ese objeto. Ese id será almacenado en el objeto relacionado.
Así pues:
Empleado, la clase "dueña", añade la propiedad private Datosprofesionales profs y guardará la columna en tablas mediante @JoinColumn. El dato guardado en la columna será la id del objeto Datosprofesionales. Y por otro lado, Datosprofesionales, añade la propiedad private Empleado idEmpleado  con mappedBy=profs, lo cual generará una referencia al id del objeto Empleado al cual va unida.
El siguiente mapeo será el de la clase Nominas hacia Empleado y Datosprofesionales. El mapeo de Nominas hacia Empleado es un @ManyToOne bilateral, lo cual significa que un objeto empleado puede tener relación con  varios objetos nomina, mientras que un objeto nomina solo puede tener relación un objeto empleado; y desde ambos deben poder accederse: la nómina debe poder acceder a los datos del empleado, y el empleado debe poder acceder a sus nóminas.
El mapeo de Nominas hacia Datosprofesionales es @ManyToOne unilateral. Cada objeto Nomina tiene relación con un solo objeto Datosprofesionales y puede acceder a esos datos porque tiene referencia. Mientras que un objeto Datosprofesionales no accede directamente a la relación con los objetos Nomina.
La clase Nominas es la clase "dueña" de las relaciones, y por ello mediante @JoinColumn añade dos columnas en su tabla con las cuales referenciada las relaciones con los otros objetos.
Al igual en la relación @OneToOne, la relación @ManyToOne añade propiedades de los objetos referenciados, en nuestro caso private Empleado idEmpleado y private Datosprofesionales idDatosProfesionales; ambas serán referencias id a los objetos correspondientes.
 Por otra parte, en el caso de Datosprofesionales no procede ningún mapeo porque era unilateral. Para nosotros no tiene utilidad que desde datos profesionales podamos acceder a las nóminas.







































En el caso de Empleados, si hay que mapear por la relación es bilateral. Empleados debe mapear @OneToMany, ya que un objeto Empleado puede tener varios objetos Nomina. Sin embargo, en este caso, hablamos de mappedBy. No se creará ninguna columna en la tabla empleados. Pero la referencia a Nomina no será un objeto Nomina, sino un private List<Nomina>nominas; esto es así porque puede haber varios objetos Nomina referenciados. Desde Empleado y mediante el List<Nomina> podremos acceder a todos los objetos Nomina referenciados.
Continuaremos con el fichero persistence.xml ...

No hay comentarios:

Publicar un comentario