2011-12-08 14 views
5

Si consideri che ci sono due entità, Dipartimento e Dipendente, dove in un reparto ci sono N dipendenti.JPA - @OneToMany update

In Departament:

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

In Impiegato:

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

Tutto funziona, ma vorrei aggiungere dipendenti al reparto, senza impostare la relazione inversa. Per esempio:

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

Quindi, la mia domanda è: c'è qualche modo che l'APP capirà che si deve propagare le modifiche verso l'altro lato della relazione, senza che esplicita che (ad esempio, da qualche annotazione.)? In altre parole, vorrei fare solo questo:

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

Grazie mille!

risposta

2

La risposta chiara è: No, non è possibile che il proprio provider JPA possa gestire automaticamente le relazioni bidirezionali nel modo in cui l'ha descritto.

È possibile comunque implementare la logica per l'impostazione associazioni bidirezionali nei tuoi soggetti, forse qualcosa in questo senso:

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

In questo caso però è necessario assicurarsi che le associazioni sono già inizializzate quando i soggetti vengono gestiti al di fuori il contesto di persistenza per evitare le eccezioni pigro di init. Questo potrebbe costringerti a passare al caricamento avido per tutte le associazioni, che generalmente non è una buona scelta. A causa della complessità delle associazioni bidirezionali io personalmente evito le associazioni bidirezionali nelle entità e le uso solo quando ci sono davvero delle buone ragioni per farlo.

1

L'unico modo per farlo è esplicitamente, come hai detto tu.

2

JPA non gestirà il grafico dell'oggetto Java per te. Puoi aggiornare il grafico degli oggetti da solo come fai nella tua domanda, o suppongo che potresti probabilmente ricaricare tutte le entità dopo aver salvato.

Non sono un fan delle relazioni bidirezionali perché possono diventare disordinati, ma se devi farlo, probabilmente vorrai selezionare un lato per essere il lato "proprietario" della relazione. Cerca dove si parla di "mappedBy" in questa pagina http://www.objectdb.com/java/jpa/entity/fields per informazioni su come farlo.

Se si dispone di un servizio che è stato implementato, è possibile fornire una chiamata di servizio che si occupa della gestione di questo tipo di materiale, quindi non si avrà la stessa possibilità di dimenticarlo in un punto del codice. e farlo correttamente negli altri 15 posti.

Problemi correlati