2012-11-27 10 views
19

Ich präsentiere die Frage mit einem Beispiel.Spring Data JPA - Warum werden Änderungen an einer zurückgegebenen Entität automatisch beibehalten?

behaupten, dass wir ein Repository wie die folgenden haben:

public interface ExampleObjectRepository extends CrudRepository<ExampleObject, Long> { 

} 

Durch die JpaRepository Schnittstelle erstreckt, erbt das ExampleObject Repository die folgende Methode:

T findOne(ID id); 

Jetzt habe ich festgestellt, dass, Wenn ich nach einem Aufruf dieser Methode einen Verweis auf ein ExampleObject erhalte, werden alle Manipulationen, die ich an dieser Methode vornimmt, automatisch in der Datenbank gespeichert. Beispiel:

ExampleObject pointInCase = exampleObjectRepository.findOne(1L); 
pointInCase.setName("Something else"); 

Um das Thema zu lesen, verstehe ich das dies bedeutet, dass ExampleObject Instanz ist not detached.

Dies widerspricht meinen Erwartungen. Ich habe erwartet, dass ich brauchen würde die Speichermethode von CrudRepository um geerbt zu verwenden, um die Änderungen zu speichern:

T save(T entity); 

würde jemand so freundlich sein, um zu bestätigen, dass Objekte von einem Spring Data JPA Repository zurück bleiben als Standard beigefügt und erläutern, wie die API verwendet wird, um eine Methode im Repository so zu markieren, dass nur abgetrennte Referenzen zurückgegeben werden.

Ich denke, dass die Änderung des Entity-Status auch seine Definition ändern kann, wenn es mit der save(T entity) Methode verwendet wird, so würde ich auch ein Verständnis dafür, wie Identität für Updates behandelt werden.

Antwort

14

Das ist ein grundlegendes Prinzip von JPA. Sie arbeiten mit angehängten (verwalteten) Entitäten und jede Änderung, die an diesen verwalteten Entitäten vorgenommen wird, wird automatisch persistent gemacht.

Wenn Sie nicht möchten, dass Ihre Änderungen persistent sind, nehmen Sie keine Änderungen vor oder führen Sie die Transaktion nicht zurück.

Das Arbeiten an losgelösten Entitäten wäre ein Albtraum, weil es verhindern würde, alle Assoziationen zu laden. Du kannst immer EntityManager.detach() auf deinen Entitäten anrufen, aber das würde ich wirklich nicht tun. Versuchen Sie einfach zu verstehen, wie es funktioniert und damit umgehen. Es gibt viel mehr Vorteile als Nachteile. Eine davon ist, dass Sie nicht einmal daran denken müssen, alle Änderungen zu speichern, die eine komplexe Geschäftslogik machen könnte, da dies alles von JPA transparent für Sie erledigt wird.

+0

Vielen Dank für Ihre Kommentare - sie sind sicherlich im Einklang mit anderen Meinungen im Büro!Werden jedoch im Fall, dass mehrere POJO-Manipulationen als Teil einer Transaktion durchgeführt werden, dieses Verhalten den transaktionalen Charakter der Methode verletzen? – 8bitjunkie

+1

Warum sollte es? Sie starten eine Transaktion, nehmen beliebig viele Änderungen an einer beliebigen Anzahl von Entitäten vor und übernehmen dann die Transaktion. Entweder werden alle Änderungen festgeschrieben oder alle Änderungen werden rückgängig gemacht. Der transaktionale Aspekt einer Methode gilt auch für jede interne Methode, die sie aufruft: Der Transaktionskontext wird propagiert. –

+0

also ... die aufrufende 'save' Methode ist unnötig, außer Sie trennen? Oder ich sollte eine andere Methode aufrufen, um sicherzustellen, dass JPA die Transaktion statt Rollback schließt? – kiedysktos

5

Sie können Ihr Repository dazu veranlassen, getrennte Entitäten zurückzugeben, wenn Ihre Transaktion auf das Repository beschränkt ist. I.e. Ihre Transaktion beginnt mit dem Eintritt in das Repository und wird geschlossen, wenn Sie das Repository verlassen.

Wenn Sie so arbeiten, müssen Sie darauf achten, dass alle notwendigen Daten auf einmal geladen werden, da sonst die Initialisierungsfehler auftreten. Aber in vielen Fällen halte ich das für wünschenswert, weil es Ihnen eine gewisse Kontrolle darüber gibt, wann und welche Daten geladen werden, die sonst bei der Verwendung von JPA leicht durch Ihre Finger gleiten.

Für Änderungen verwende ich einen anderen Transaktionsbereich, der den gesamten Prozess des Ladens, Änderns (und implizit Persistent) umschließt.

Verwandte Themen