Este grupo de trabajo ha pasado horas buscando la solución a tu pregunta, te compartimos la soluciones de modo que esperamos que te resulte de mucha apoyo.
Solución:
La principal diferencia es que la relación bidireccional proporciona acceso de navegación en ambas direcciones, de modo que puede acceder al otro lado sin consultas explícitas. También le permite aplicar opciones en cascada en ambas direcciones.
Tenga en cuenta que el acceso de navegación no siempre es bueno, especialmente para las relaciones “uno a muchos” y “muchos a muchos”. Imagina un Group
que contiene miles de User
s:
-
¿Cómo accederías a ellos? con tantos
User
s, generalmente necesita aplicar algún filtrado y/o paginación, por lo que necesita ejecutar una consulta de todos modos (a menos que use el filtrado de colección, que me parece un truco). Algunos desarrolladores tienden a aplicar filtros en la memoria en tales casos, lo que obviamente no es bueno para el rendimiento. Tenga en cuenta que tener una relación de este tipo puede alentar a este tipo de desarrolladores a usarla sin tener en cuenta las implicaciones de rendimiento. -
¿Cómo agregarías nuevos
User
s a laGroup
? Afortunadamente, Hibernate mira el lado propietario de la relación cuando la persiste, por lo que solo puede configurarUser.group
. Sin embargo, si desea mantener la consistencia de los objetos en la memoria, también debe agregarUser
paraGroup.users
. Pero haría que Hibernate buscara todos los elementos deGroup.users
de la base de datos!
Por lo tanto, no puedo estar de acuerdo con la recomendación de Mejores prácticas. Debe diseñar relaciones bidireccionales con cuidado, teniendo en cuenta los casos de uso (¿necesita acceso de navegación en ambas direcciones?) y las posibles implicaciones de rendimiento.
Ver también:
- Disuasión de relaciones “ToMany” en modelos JPA
- Problemas de rendimiento de las colecciones mapeadas de Hibernate
Hay dos diferencias principales.
Acceso a los lados de la asociación
El primero está relacionado con cómo accederás a la relación. Para una asociación unidireccional, puede navegar por la asociación solo desde un extremo.
Entonces, para un unidireccional @ManyToOne
asociación, significa que solo puede acceder a la relación desde el lado del niño donde el extranjero key reside
Si tienes unidireccional @OneToMany
asociación, significa que solo puede acceder a la relación desde el lado principal que administra el extranjero key.
Para el bidireccional @OneToMany
asociación, puede navegar por la asociación de ambas formas, ya sea desde el lado principal o desde el lado secundario.
También debe usar métodos de utilidad de agregar/eliminar para asociaciones bidireccionales para asegurarse de que ambos lados estén correctamente sincronizados.
Rendimiento
El segundo aspecto está relacionado con el rendimiento.
- Para
@OneToMany
las asociaciones unidireccionales no funcionan tan bien como las bidireccionales. - Para
@OneToOne
una asociación bidireccional hará que el padre sea buscado ansiosamente si Hibernate no puede decir si se debe asignar el Proxy o un null valor. - Para
@ManyToMany
el tipo de colección hace una gran diferencia ya queSets
actuar mejor queLists
.
En términos de codificación, una relación bidireccional es más compleja de implementar porque la aplicación es responsable de mantener ambos lados sincronizados de acuerdo con la especificación JPA 5 (en la página 42). Desafortunadamente, el ejemplo dado en la especificación no da más detalles, por lo que no da una idea del nivel de complejidad.
Cuando no se usa un caché de segundo nivel, generalmente no es un problema no tener los métodos de relación implementados correctamente porque las instancias se descartan al final de la transacción.
Cuando se usa el caché de segundo nivel, si algo se corrompe debido a métodos de manejo de relaciones implementados incorrectamente, esto significa que otras transacciones también verán los elementos dañados (el caché de segundo nivel es global).
Una relación bidireccional implementada correctamente puede simplificar las consultas y el código, pero no debe usarse si realmente no tiene sentido en términos de lógica empresarial.