2011-11-29 45 views
11

Sto facendo alcune operazioni CRUD utilizzando JPA. Per aggiornare un oggetto che è il modo giusto di fare?Qual è il modo migliore per aggiornare l'entità in JPA

Tramite query di aggiornamento o tramite il metodo find di EntityManager?
Ho un oggetto Employee che devo aggiornare. Qual è la strada giusta? Per semplicità, il metodo find è buono, quindi ho utilizzato il metodo find().

Per favore guidami.

risposta

26

Utilizzare executeUpdate() su Query API è più veloce perché ignora il contesto persistente. Tuttavia, il contesto persistente by-pass causerebbe lo stato di istanza nella memoria e i valori effettivi di tale record nel DB non sono sincronizzati.

consideri il seguente esempio:

Employee employee= (Employee)entityManager.find(Employee.class , 1); 
entityManager 
    .createQuery("update Employee set name = \'xxxx\' where id=1") 
    .executeUpdate(); 

Dopo il lavaggio, il nome nel DB viene aggiornata al nuovo valore, ma l'istanza dipendente nella memoria conserva ancora il valore originale Avete chiamare entityManager.refresh(employee) per ricaricare il nome aggiornato dal DB all'istanza dipendente. Sembra strano se i codici devono ancora manipolare l'istanza dipendente dopo lo svuotamento, ma si dimentica di aggiornare() l'istanza dipendente in quanto l'istanza dipendente contiene ancora i valori originali.

Normalmente, executeUpdate() viene utilizzato nel processo di aggiornamento di massa in quanto è più veloce a causa bypassando il contesto persistente

Il modo giusto per aggiornare un'entità è che è sufficiente impostare le proprietà che si desidera aggiornato attraverso i setter e Lascia che l'JPA generi l'aggiornamento SQL per te durante lo svuotamento invece di scriverlo manualmente.

Employee employee= (Employee)entityManager.find(Employee.class ,1); 
    employee.setName("Updated Name"); 
+0

@Ken Chan, 'entityManager.find (Employee.class, 1)' e 'employee.setName (" Nome aggiornato) 'causa due query: seleziona e aggiorna, e se vogliamo una sola query quando aggiornamento entità? È possibile? – inherithandle

+0

Odio il modo in cui gli aggiornamenti vengono apportati in JPA. Può causare molti aggiornamenti accidentali ed effetti collaterali. A volte non si sa nemmeno che si sta facendo un aggiornamento. – ceklock

+0

Un modo per aggiornare tutte le proprietà con un nuovo oggetto anziché eseguirne uno alla volta? –

4

Dipende da cosa si vuole fare, ma come hai detto, ottenere un riferimento di entità usando find() e quindi l'aggiornamento di quell'entità è il modo più semplice per farlo.

Non mi preoccuperei delle differenze di prestazioni dei vari metodi, a meno che non si abbiano forti indicazioni che ciò sia davvero importante.

+0

Possiamo usare find() per ottenere obj aObj e quindi utilizzare aObj = new MyObj (// ...) per aggiornare l'oggetto? Non ho visto esempi come questo ovunque –

0

Dipende dal numero di entità che verranno aggiornate, se si dispone di un numero elevato di entità che utilizzano l'istruzione JPA Query Update è migliore in quanto non è necessario caricare tutte le entità dal database, se si desidera aggiornare solo un'entità che utilizza quindi trova e aggiorna va bene.

+1

In caso di aggiornamenti di massa. Ma ciò interrompe anche l'isolamento tra codice e database - la maggior parte dei vantaggi di JPA –

+0

sì, ma ci sono casi in cui non è possibile recuperare tutti i record e quindi aggiornarli, non è la soluzione accettabile in un determinato contesto, quindi il suo utilizzo dipende dal contesto. Inoltre quando ho detto Update Query intendevo "Query di aggiornamento JPA" non "Query di aggiornamento SQL", quindi sei ancora praticamente indipendente dal database. – mprabhat

+0

La query di aggiornamento JPA viene convertita in query SQL e interrompe ancora l'astrazione degli oggetti. Ma ci sono casi d'uso legittimi –

Problemi correlati