2011-09-11 12 views
7

En un proyecto basado en Spring/Hibernate, tenemos una relación de uno a varios entre dos entidades. Las operaciones requeridas son:¿Deberían evitarse las asociaciones bidireccionales de Hibernate?

  • encontrar el padre del niño;
  • encontrar a los hijos del padre;
  • cuando se eliminan los padres, también tenemos que eliminarlos;
  • mass-create the children.

Se nos ocurrió dos formas de implementar esto.

  1. Bidirectional association: entidad secundaria tiene @ManyToOne columna vinculándola a los padres, y los padres tienen @OneToMany colección perezoso cargado de los niños. Todas las operaciones anteriores pueden realizarse en el modelo:

    child.getParent(); 
    parent.getChildren(); //lazy loading 
    session.delete(parent); //cascade removal of the children does the trick here 
    session.save(parent); //cascade persist created the children 
    
  2. unidireccional asociación: Entidad niño tiene @ManyToOne columna vinculándola a los padres, pero el padre no tiene ningún vínculo con los niños. La mayoría de las operaciones se deben realizar en los métodos de servicio:

    child.getParent(); //still in the model 
    Collection<Child> findChildren(Parent parent); //service method in ChildService 
    void deleteChildren(Parent parent); //service method in ChildService 
    void createChild(Parent parent, ... childAttributes); //service method in ChildService invoked for each new child. 
    

El primer enfoque parece ser más fácil de implementar (se puede volver a utilizar Hibernate funcionalidad en cascada) pero algunos de vernos las asociaciones bidireccionales como una causa potencial de problemas .

¿Cuál debería ser una mejor opción de diseño? ¿Existen problemas, desempeño o diseño conocidos, creados por el enfoque bidireccional?

+0

¿Conoces una fuente que explique cómo hacer que funcione lazyloading? Tuve problemas con esto en un proyecto JSF. –

+1

"algunos de nosotros consideramos que las asociaciones bidireccionales son una posible causa de problemas". ¿Puede nombrar estos posibles problemas? –

Respuesta

3

Si sus consultas hacen lo mismo que las consultas ejecutadas detrás de la escena por Hibernate cuando carga perezosamente a los niños, no veo lo que gana al no usar una asociación OneToMany.

Si sabe lo que está haciendo y lo que cada método llama a su entidad en términos de consultas a la base de datos, no debería tener ningún problema con las colecciones asignadas. A veces es conveniente recorrerlos, a veces es mejor usar una consulta ad-hoc para evitar demasiados viajes de ida y vuelta a la base de datos. La clave es entender lo que sucede.

Tener una asociación también puede ser muy útil solo para poder navegar en consultas HQL, no necesariamente para llamar al getter asociado.

0

Siempre que se encuentre en una situación en la que la carga diferida realmente funciona para usted, no he visto un problema real con las relaciones bidireccionales. Una vez trabajé en una aplicación Flex donde se usaba Hibernate y las relaciones bidireccionales a menudo causaban que la base de datos completa se descargara cuando los datos se serializaban al cliente.

YMMV

0

La respuesta por @JB Nizet dice que casi todos, sólo una cosa más: En cuanto a las muestras de llamadas a métodos en los que posteaste, el método bidireccional es probable que el código de lógica de negocio un poco más legible.

-1

Sí, Eso debe evitarse tanto como sea posible. si realmente piensas, ese es tu requisito, entonces solo usa bidireccional. p.ej. Emp y Dept, cada emp tiene un departamento, pero el departamento tiene muchos empleados. emp debe saber acerca de su departamento, pero no es obligatorio que el departamento también conozca su departamento.

+1

Esto parece más un comentario que una respuesta. – mattias

Cuestiones relacionadas