hibernate - one - Intentando entender la importancia de un lado dueño de una relación uno-muchos en ORM
one to many hibernate (2)
Aunque mi pregunta está expresada específicamente sobre la forma en que se representan las relaciones de Entity en el marco Play, que utiliza Hibernate, estoy seguro de que este es un concepto general.
Cuando tenemos una relación de uno a muchos, siempre se nos pide que especifiquemos el lado propietario.
Entonces, por ejemplo, si tuviéramos una relación uno a muchos entre Person y PhoneNumber, escribiríamos un código como este.
@Entity
class Person {
@OneToMany(mappedBy="person")
public Set<PhoneNumber> phoneNumbers;
}
@Entity
class PhoneNumber {
@ManyToOne
public Person person;
}
En el código anterior, la entidad propietaria es PhoneNumber. ¿Cuáles son los pros y los contras de que cada lado sea la entidad propietaria?
Me doy cuenta de que cuando la entidad propietaria es PhoneNUmber, la relación representada es ManyToOne, que no dará como resultado una tabla de unión, mientras que cuando el lado propietario sea Person, la relación representada será OneToMany, en cuyo caso se creará una tabla de relación.
¿Es esta la razón principal para determinar el lado propietario, o hay otras razones también?
Actualización: Me acabo de dar cuenta de que este hilo proporciona parte de la respuesta, pero espero que haya otros puntos también.
Con la mayoría de las capas ORM tienes el concepto de carga diferida. Cuando creas un objeto Persona, no cargará los teléfonos configurados a menos que se te pida. En ocasiones, la forma en que desea buscar datos también puede dictar cómo almacenarlos.
Por ejemplo, si desea mostrar a la persona primero y luego mostrar los números de teléfono a pedido, entonces mantener las referencias de persona en el teléfono está bien. Primero activa una consulta simple para cargar datos de personas y luego solo busca números telefónicos basados en una persona (ya cargada) id (otra consulta simple)
Mientras que para mostrar datos de persona + teléfono de una vez, preferiría tener una tabla de unión donde simplemente puede cargar datos basados en la tabla de persona + tabla de unión de persona-teléfono usando la identificación de persona como claves en la tabla de teléfono, todo de una vez. Aquí sería costoso realizar búsquedas sin una tabla de relaciones.
Pero francamente, si piensas en SQL en lugar de ORM, entonces irías con una tabla de relaciones cada vez: D
Un punto importante a tener en cuenta es que la relación propietaria es la que realmente persiste en la relación de salvación. Con un ejemplo:
Person person = new Person();
PhoneNumber pn = new PhoneNumber();
pn.phone = "12345678";
person.phoneNumbers.add(pn);
session.save(person);
La relación no se guarda de hecho si recargas la entidad desde la base de datos no verás números. Para agregar realmente la relación que necesita para configurar a la persona en el lado del propietario (PhoneNumber) y luego guardar.
// the relation is not saved
Person loadedPerson = (Person)session.load(Person.class, person.id);
System.out.println(loadedPerson.phoneNumbers.size()); // prints 0!
pn.person = person;
session.save(pn);
loadedPerson = (Person)session.load(Person.class, person.id);
System.out.println(loadedPerson.phoneNumbers.size()); // prints 1