2011-12-08 38 views
5

Tenga en cuenta que hay dos entidades, Departamento y Empleado, donde en un departamento hay N empleados.JPA - @OneToMany actualización

En Departament:

@OneToMany(mappedBy = "department", fetch = FetchType.EAGER) 
private Collection<Employee> employees = new ArrayList<Employee>(); 

En Empleado:

@ManyToOne(fetch = FetchType.EAGER) 
private Department department; 

Todo funciona, pero me gustaría añadir que los empleados del departamento, sin establecer la relación inversa. Por ejemplo:

// I will add two employees to a department 
department.getEmployees().add(employee1); 
department.getEmployees().add(employee2); 

// In fact, it is necessary to set the opposite side of the relationship 
employee1.setDepartment(department); 
employee2.setDepartment(department); 

entityManager.merge(department);  
//... 

Por lo tanto, mi pregunta es: ¿hay alguna manera de que la APP entender que se debe propagar los cambios en el otro lado de la relación sin que explícitamente que (por ejemplo, por alguna anotación.)? En otras palabras, me gustaría hacer solo esto:

department.getEmployees().add(employee1); 
department.getEmployees().add(employee2); 
entityManager.merge(department); 

¡Muchas gracias!

Respuesta

2

La respuesta clara es: No, no es posible que su proveedor de JPA maneje automáticamente las relaciones bidireccionales como lo describió.

Sin embargo, puede aplicar la lógica para establecer asociaciones bidireccionales en sus entidades, tal vez algo en este sentido:

class Department { 

    public void addEmployee(Employee empl) { 
    if (empl.getDepartment() != null && !this.equals(empl.getDepartment())) { 
     empl.getDepartment().getEmployees().remove(empl); 
    } 
    empl.setDepartment(this); // use the plain setter without logic 
    this.employees.add(empl); 
    } 
} 


class Employee { 
    // additional setter method with logic 
    public void doSetDepartment(Department dept) { 
    if (this.department != null && !this.department.equals(dept)) { 
     this.department.getEmployees().remove(this); 
    } 
    dept.getEmployees().add(this); 
    this.department = dept; 
    } 
} 

En este caso, sin embargo, debe asegurarse de que las asociaciones ya se inicializan cuando las entidades se manejan fuera el contexto de persistencia para evitar excepciones de inicio perezoso. Esto podría forzarlo a cambiar a una carga ansiosa para todas las asociaciones, lo que generalmente no es una buena opción. Debido a la complejidad de las asociaciones bidireccionales yo personalmente evito las asociaciones bidireccionales en las entidades y las uso solo cuando hay realmente buenas razones para ello.

1

La única manera de hacerlo es explícitamente, como usted mencionó.

2

JPA no gestionará su gráfico de objetos de Java por usted. Puede actualizar el gráfico de objetos usted mismo como lo hace en su pregunta, o supongo que probablemente podría volver a cargar todas las entidades después de guardarlas.

No soy partidario de las relaciones bidireccionales porque pueden desordenarse, pero si debe hacerlo, probablemente querrá seleccionar un lado para ser el lado "propietario" de la relación. Busque dónde se habla de "mappedBy" en esta página http://www.objectdb.com/java/jpa/entity/fields para obtener información sobre cómo hacerlo.

Si tiene un servicio que ha implementado, puede proporcionar una llamada de servicio que se encargue de gestionar este tipo de cosas, entonces no tendrá la gran posibilidad de olvidarlo en un lugar de su código y hacerlo correctamente en los otros 15 lugares.

Cuestiones relacionadas