2 Stimmen

Berechnung vor der Aktualisierung der Datenbank

Ich verwende Play Framework und habe ein, wie ich glaube, sehr häufiges Persistenzproblem:

  • Ich zeige ein Formular mit Werten aus der Datenbank und einem Feld "Menge" an.
  • Der Benutzer aktualisiert das Formular und ändert den Wert der "Menge".
  • Er klickt auf die Schaltfläche "Speichern".
  • In der aufgerufenen Controller-Methode möchte ich den alten Wert der "Menge" abrufen und die Differenz zwischen dem neuen und dem alten Wert berechnen, bevor ich die DB aktualisiere
  • Um das zu machen, verwende ich findById (vor dem Aufruf der object.save-Methode), aber es gibt mir den neuen Wert, nicht den alten: es sieht anscheinend in irgendeinem Cache (welcher?), anstatt die DB abzufragen

\=> Ist das normal? Wie kann ich den alten Wert ermitteln, meine Berechnung durchführen und dann beibehalten?

Vielen Dank für Ihre Hilfe, ich möchte keine alten/neuen Werte in meiner DB verwalten...ich bin mir sicher, dass das eine schlechte Praxis ist!

アップデイト

    public static void save(@Valid Lot lot) {
     History element = new History();
     element.date = new Date();
     //HERE below it returns the new value, not the old one
     Lot databaseLot = Lot.findById(lot.id); 
     element.delta= databaseLot.quantity - lot.quantity;
     element.save();
     lot.save();
     list(null, null, null, null);
}

0 Stimmen

Können Sie den Code des Controllers angeben? Es ist schwer zu erraten, was da passiert. Ich würde vermuten, dass es ein Bindungsproblem ist.

3voto

Codemwnci Punkte 52604

Das liegt daran, dass Play hier etwas für Sie zaubert.

Wenn Sie ein JPA-Objekt an Ihren Controller übergeben, das eine ID enthält, ruft Play dieses JPA-Objekt automatisch aus der Datenbank ab. Wenn Sie siehe hier wird dies etwas ausführlicher erklärt. Er besagt (und unter der Annahme eines Aktionsaufrufs, der ein User JPA Pojo übergibt)

Sie können ein JPA-Objekt automatisch binden u Bindung.

Sie können die user.id selbst in das Feld Wenn Play das id-Feld findet, lädt es die passende Instanz aus der Datenbank, bevor es sie bearbeitet. Die anderen Parameter, die von der HTTP Anfrage angegebenen Parameter werden dann angewendet. Sie können sie also direkt speichern.

Wie können Sie das beheben? Ich denke, der einfachste Weg ist, die ID nicht als Teil des Pojo-Objekts zu übergeben und die ID als separaten Parameter zu übergeben, damit Play glaubt, dass das Objekt nicht automatisch aus der Datenbank abgerufen werden muss.

Eine alternative Methode besteht darin, eine Setter-Methode für das Mengenfeld zu haben, die das Delta aktualisiert. Play ruft also automatisch das Objekt aus der DB ab und ruft dann Ihre Setter-Methode auf, um die Werte zu aktualisieren (wie bei einer normalen POJO-Bindung). Im Rahmen dieses Vorgangs werden Ihre neue Menge und das Delta festgelegt. Perfekt! Dies ist meiner Meinung nach die beste Option, da sie auch sicherstellt, dass die Geschäftslogik sauber in Ihrem Model und nicht in Ihrem Controller bleibt.

0voto

Mac Punkte 1630

Ich kann nicht speziell für das Play Framework sprechen, aber in JPA ist die EntityManager speichert Objekte für ihre gesamte Lebensdauer, es sei denn, sie wird ausdrücklich geleert. Aus diesem Grund erhalten Sie bei der Abfrage eines Objekts, das der Kontext bereits verwaltet, nur die gecachte Version. Außerdem hört es sich so an, als ob die EM, die Sie erhalten, deklariert ist als EXTENDED was dazu führt, dass derselbe EM in mehreren Anfragen verwendet wird (oder das Framework führt die Suche heimlich durch und legt die Werte fest, bevor Sie sie bearbeiten können).

Sie müssen entweder diesen Cache umgehen oder Play so konfigurieren, dass es einen TRANSACTION -skalierten Persistenzkontext (auch bekannt als EntityManager). Bei letzterem kann ich Ihnen nicht helfen, aber ersteres ist einfach genug.

int newQuantity = entity.getQuantity();
entityManager.refresh(entity);
// enity.getQuantity() should now give you the old value
// Do your calculation
// entity.setQuantity(newQuantity);

Am Ende der Transaktion sollte Ihr neuer Status gespeichert sein.

0voto

Arasu Punkte 2058

Sie können den Mengenwert in einem verborgenen Text speichern und diesen verarbeiten

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X