2011-12-08 10 views
5

Uważa się, że istnieją dwa podmioty, Departament i Pracownik, w którym w jednym dziale pracuje N pracowników.JPA - @OneToMany aktualizacja

W Klinice:

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

W Pracownika:

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

Wszystko działa, ale chciałbym dodać pracowników do działu bez zestawu relacji odwrotnej. Na przykład:

// 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);  
//... 

Więc moje pytanie brzmi: czy jest jakiś sposób, że WZP będzie zrozumieć, że powinien propagować zmiany na drugiej stronie relacji bez I wyraźnie zaznaczyć, że (na przykład za pośrednictwem adnotacji.)? Innymi słowy, chciałbym zrobić tylko to:

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

Wielkie dzięki!

Odpowiedz

2

Oczywistą odpowiedzią jest: Nie, nie jest możliwe, że dostawca JPA może automatycznie obsługiwać relacje dwukierunkowe w sposób opisany przez użytkownika.

Można jednak realizować logikę do ustawiania skojarzeń dwukierunkowych w swoich jednostkach, może coś wzdłuż tych linii:

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; 
    } 
} 

W tym przypadku należy jednak upewnić się, że stowarzyszenia są już zainicjowany, gdy podmioty są obsługiwane poza kontekst utrwalania, aby uniknąć leniwych wyjątków init. Może to zmusić Cię do przejścia do szybkiego ładowania wszystkich skojarzeń, co zwykle nie jest dobrym wyborem. Z powodu złożoności skojarzeń dwukierunkowych osobiście unikam dwukierunkowych asocjacji w jednostkach i używam ich tylko wtedy, gdy istnieją ku temu dobre powody.

1

Jedynym sposobem, aby to zrobić, jest jawnie, jak wspomniałeś.

2

JPA nie będzie zarządzać twoim diagramem obiektów Java dla ciebie. Możesz zaktualizować wykres obiektu samodzielnie, tak jak w pytaniu, lub prawdopodobnie prawdopodobnie ponownie załaduje wszystkie obiekty po zapisaniu.

Nie jestem fanem dwukierunkowych relacji, ponieważ mogą się uprzykrzyć, ale jeśli musisz to zrobić, prawdopodobnie będziesz chciał wybrać jedną stronę, która będzie "właścicielem" strony relacji. Aby dowiedzieć się, jak to zrobić, zobacz, gdzie mówi o "mappedBy" na stronie http://www.objectdb.com/java/jpa/entity/fields.

Jeśli posiadasz usługę, którą zaimplementowałeś, możesz podać zgłoszenie serwisowe, które zajmuje się zarządzaniem tego rodzaju rzeczami, wtedy nie będziesz miał tak wielkiej szansy na zapomnienie go w jednym miejscu w kodzie i robiąc to poprawnie w pozostałych 15 miejscach.

Powiązane problemy