2017-01-23 3 views
0

Projekt play Rahmen 1.3.3 verwendet Ich habe einen solchen Controller:play Rahmen 1.3.3 und Hibernate Cache

public static void save(Item item) { 
    if (item.id != null) { //It means that item is not new, it is being edited 
     Item existingOldItem = Item.findById(item.id); 
     //Here I should have an old version of an item as "existingOldItem" 
     //and new one coming from http request as "item" 
    } 

Aber das Problem ist Gegenstand und existingOldItem sind sehr identisch. Die Item.findById-Zeile gibt mir kein altes Element aus der Datenbank zurück, sondern gibt das neue Element aus der http-Anforderung zurück (dasselbe mit JPA.em(). CreateQuery). Ich nehme an, dass Play Framework ein neues Element in einem Cache sendet, und findById gibt das Element aus dem Cache zurück, nicht aus einer Datenbank. Könnte mir bitte jemand die Logik erklären, die dahinter steckt und wie man das Problem lösen kann.

Antwort

3

Das Problem ist Artikel und existingOldItem sind sehr identisch. Item.findById Zeile gibt mir kein altes Element aus der Datenbank

Das ist das erwartete Verhalten. Item.findById() gibt das alte Element zurück, wie vom HTTP-Client geändert. Werfen Sie einen Blick auf JPA object binding aus dem Play! Dokumentation, um das Anrufmuster zu sehen.

Bitte, könnte jemand mir erklären, die Logik dahinter ...

Kurz gesagt, der HTTP-Client eine ID des Positionssatzes und seine neue Eigenschaftswerte in der HTTP-Anforderung zur Verfügung zu stellen wird erwartet, . Abspielen! Richtet den Parameter item bereit zum Speichern ein, sucht das Objekt in der Datenbank und ändert seine Eigenschaften entsprechend den POST-Parametern. Sie sollten also kein "altes" und ein "neues" Objekt haben, Sie sollten einfach ein "Objekt" -Objekt haben, das alt oder neu sein kann, abhängig davon, ob die vom HTTP-Client angegebene ID gefunden wurde die Datenbank. Ihre Controller-Aktion muss nur item.save() aufrufen.

Die Magie ist in JPAPlugin.bind. Wie Sie vermuten, sucht es zuerst nach dem Objekt in der Datenbank. Wenn das Objekt gefunden wird, ruft es Item.edit() mit diesem Objekt auf. Dies ist auch magisch und die Standardimplementierung setzt alle Eigenschaften von Item, für die es passende HTTP-Parameter gibt.

... und die Möglichkeiten, das Problem zu lösen.

Ich bin mir nicht sicher, was das Problem betrachten zu sein, aber wenn Sie ein altes wollen und ein neues Element, dann sollte der Kunde keine item.id Parameter liefern. Wenn Ihnen das nicht gefällt, spielen Sie! gräbt in Ihre Datenbank ein, um den item Parameter zu instanziieren, dann können Sie einen benutzerdefinierten Binder bereitstellen oder die Controller-Aktion eine ähnlich aussehende POJO-Klasse anstelle der JPA-Klasse akzeptieren lassen.

+0

Danke! Ist es ein normales Verhalten eines Web-Frameworks mit JPA oder ist es nur ein Spiel? Ding? –

+0

Das ist Spielen! Spezifisch. Wenn andere Web-Frameworks dasselbe tun, ist es Zufall. Ich würde mich wundern, wenn ein anderes Framework dies tut, weil item.save() ein Play ist! Erfindung und nicht, wie JPA-Entitäten normalerweise arbeiten. Wenn ein anderes Framework das JPA-Objekt im Speicher änderte, löschte Hibernate möglicherweise die Änderungen an der Datenbank, ohne der Anwendungslogik die Möglichkeit zu geben, sie zurückzuweisen. In Play! Muss die Anwendungslogik jedoch save() aufrufen, damit die Änderungen gelöscht werden. –

Verwandte Themen