tutorial para for español java hibernate orm jpa mapping

java - para - ¿Cuál es el "lado propietario" en un mapeo ORM?



hibernate tutorial (2)

Puedes imaginar que el lado propietario es la entidad que tiene la referencia al otro. En tu extracto, tienes una relación uno a uno. Como es una relación simétrica , terminarás teniendo eso si el objeto A está en relación con el objeto B, entonces también lo viceversa es verdadero.

Esto significa que guardar en el objeto A una referencia al objeto B y guardar en el objeto B una referencia al objeto A será redundante: es por eso que usted elige qué objeto "posee" al otro que tiene la referencia al mismo.

Cuando tenga una relación de uno a varios, los objetos relacionados con la parte "muchos" serán del lado propietario, de lo contrario, tendría que almacenar muchas referencias de un solo objeto a una multitud. Para evitar eso, cada objeto en la segunda clase tendrá un puntero al único al que se refieren (para que sean los dueños).

Para una relación de muchos a muchos, dado que necesitarás una tabla de mapeo separada de todos modos, no habrá ningún lado propietario.

En conclusión, el lado propietario es la entidad que tiene la referencia al otro.

¿Qué significa exactamente el lado propietario ? ¿Qué es una explicación con algunos ejemplos de mapeo ( uno a muchos, uno a uno, muchos a uno )?

El siguiente texto es un extracto de la descripción de @OneToOne en la documentación de Java EE 6. Puedes ver el lado de posesión del concepto en él.

Define una asociación de un solo valor para otra entidad que tiene una multiplicidad de uno a uno. Normalmente no es necesario especificar explícitamente la entidad objetivo asociada, ya que normalmente se puede deducir del tipo de objeto al que se hace referencia. Si la relación es bidireccional, el lado no propietario debe usar el elemento mappedBy de la anotación OneToOne para especificar el campo de relación o propiedad del lado propietario.


¿Por qué es necesaria la noción de un lado propietario?

La idea de un lado propietario de una relación bidireccional proviene del hecho de que en las bases de datos relacionales no existen relaciones bidireccionales como en el caso de los objetos. En las bases de datos solo tenemos relaciones unidireccionales: claves foráneas.

¿Cuál es el motivo del nombre ''lado propietario''?

El lado propietario de la relación rastreada por Hibernate es el lado de la relación que posee la clave foránea en la base de datos.

¿Cuál es el problema que resuelve la noción de lado propietario?

Tomemos el ejemplo de dos entidades mapeadas sin declarar un lado propietario:

@Entity @Table(name="PERSONS") public class Person { @OneToMany private List<IdDocument> idDocuments; } @Entity @Table(name="ID_DOCUMENTS") public class IdDocument { @ManyToOne private Person person; }

Desde el punto de vista OO este mapeo no define una relación bidireccional, sino dos relaciones unidireccionales separadas.

La asignación crearía no solo tablas PERSONS e ID_DOCUMENTS , sino que también crearía una tercera tabla de asociación PERSONS_ID_DOCUMENTS :

CREATE TABLE PERSONS_ID_DOCUMENTS ( persons_id bigint NOT NULL, id_documents_id bigint NOT NULL, CONSTRAINT fk_persons FOREIGN KEY (persons_id) REFERENCES persons (id), CONSTRAINT fk_docs FOREIGN KEY (id_documents_id) REFERENCES id_documents (id), CONSTRAINT pk UNIQUE (id_documents_id) )

Observe la clave primaria pk en ID_DOCUMENTS solamente. En este caso, Hibernate rastrea ambos lados de la relación de forma independiente: si agrega un documento a la relación Person.idDocuments , inserta un registro en la tabla de asociación PERSON_ID_DOCUMENTS .

Por otro lado, si llamamos a idDocument.setPerson(person) , cambiamos la clave externa person_id en la tabla ID_DOCUMENTS . Hibernate está creando dos relaciones unidireccionales (clave externa) en la base de datos, para implementar una relación de objeto bidireccional.

Cómo la noción del lado dueño resuelve el problema:

Muchas veces lo que queremos es solo una clave externa en la tabla ID_DOCUMENTS hacia PERSONS y la tabla de asociación adicional.

Para resolver esto, debemos configurar Hibernate para detener el seguimiento de las modificaciones en la relación Person.idDocuments . Hibernate solo debe rastrear el otro lado de la relación IdDocument.person , y para hacerlo agregamos mappedBy :

@OneToMany(mappedBy="person") private List<IdDocument> idDocuments;

¿Qué significa mappedBy?

Esto significa algo así como: "las modificaciones en este lado de la relación ya están mapeadas por el otro lado de la relación IdDocument.person, por lo que no es necesario rastrearlo aquí por separado en una tabla adicional".

¿Hay GOTCHAS, consecuencias?

Usando mappedBy , si solo llamamos a person.getDocuments().add(document) , la clave foránea en ID_DOCUMENTS NO se vinculará al documento nuevo, ¡porque este no es el lado dueño / seguimiento de la relación!

Para vincular el documento a la nueva persona, debe llamar explícitamente a document.setPerson(person) , porque ese es el lado propietario de la relación.

Al utilizar mappedBy , es responsabilidad del desarrollador saber cuál es el lado propietario y actualizar el lado correcto de la relación para activar la persistencia de la nueva relación en la base de datos.