¿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 propietario del concepto .
Define una asociación de un solo valor a otra entidad que tiene multiplicidad uno a uno. Normalmente no es necesario especificar explícitamente la entidad objetivo asociada, ya que generalmente se puede inferir 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 la propiedad del lado propietario.
Respuestas:
¿Por qué es necesaria la noción de un lado propietario?
La idea del lado propietario de una relación bidireccional proviene del hecho de que en las bases de datos relacionales no hay relaciones bidireccionales como en el caso de los objetos. En las bases de datos solo tenemos relaciones unidireccionales: claves foráneas.
¿Cuál es la razón 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 externa en la base de datos.
¿Cuál es el problema que resuelve la noción de ser propietario?
Tome un ejemplo de dos entidades mapeadas sin declarar un lado propietario:
Desde el punto de vista de OO, este mapeo define no una relación bidireccional, sino dos relaciones unidireccionales separadas.
La asignación crearía no solo tablas
PERSONS
yID_DOCUMENTS
, sino que también crearía una tercera tabla de asociaciónPERSONS_ID_DOCUMENTS
:Note la clave principal
pk
enID_DOCUMENTS
solamente. En este caso, Hibernate rastrea ambos lados de la relación de forma independiente: si agrega un documento a una relaciónPerson.idDocuments
, inserta un registro en la tabla de asociaciónPERSON_ID_DOCUMENTS
.Por otro lado, si llamamos
idDocument.setPerson(person)
, cambiamos la clave externa person_id en la tablaID_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 de ser propietario resuelve el problema:
Muchas veces lo que queremos es solo una clave externa en la tabla
ID_DOCUMENTS
haciaPERSONS
y la tabla de asociación adicional.Para resolver esto, necesitamos configurar Hibernate para que deje de rastrear las modificaciones en relación
Person.idDocuments
. Hibernate solo debe rastrear el otro lado de la relaciónIdDocument.person
, y para ello agregamos mappedBy :¿Qué significa mappedBy?
¿Hay alguna GOTCHA, consecuencias?
Usando mappedBy , Si sólo nos llamamos
person.getDocuments().add(document)
, la clave externa deID_DOCUMENTS
lo NO estar relacionado con el nuevo documento, ya que este no es el / lado propietario seguimiento de la relación!Para vincular el documento a la nueva persona, debe llamar explícitamente
document.setPerson(person)
, porque ese es el lado propietario de la relación.Al usar 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.
fuente
person.getDocuments().add(document)
", hibernate actualiza la clave foráneaID_DOCUMENTS
.@OneToMany
anotación que se puede establecer en PERSIST en este caso, hibernate guardará todas las entidades vinculadas en la base de datos. ¿Alguien puede aclarar esto? ¿Por qué el autor dice que hibernate no rastreará los cambios en el lado no propietario? Sino que de hecho hibernado realiza el seguimiento?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. Ya que es simétrico relación , terminarás teniendo que si el objeto A está en relación con el objeto B, entonces también lo contrario es cierto.
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 elige qué objeto "posee" el otro que tiene la referencia a él.
Cuando tiene una relación de uno a muchos, los objetos relacionados con la parte "muchos" serán el 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 (por lo que son el lado propietario).
Para una relación de muchos a muchos, ya que necesitará 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.
fuente
@ManyToMany
relaciones también tienen lados propietarios. Del mismo modo, las@OneToMany
relaciones pueden usar tablas de unión, y aún debe especificar un lado propietario.