OptimisticLockException mit Ebean/Spielen
Habe ich ein Spiel 2.1.3 Java-app mit Ebean. Ich bin immer der OptimisticLockException unten.
[OptimisticLockException: Data has changed. updated [0] rows sql[update person
set name=? where id=? and email=? and name=? and password is null and created=?
and deleted is null] bind[null]]
Ich verstehe, dass er versucht, mir zu sagen, der Datensatz geändert hat zwischen, wenn ich es lese und wenn ich versuchte, es zu schreiben. Aber die einzige Veränderung, die geschieht in dieser Methode.
public void updateFromForm(Map<String, String[]> form) throws Exception {
this.name = form.get("name")[0];
String password = form.get("password")[0];
if (password != null && password.length() != 0) {
String hash = Password.getSaltedHash(password);
this.password = hash;
}
this.update();
}
Mache ich das falsch? Ich sah eine ähnliche Logik in zentasks. Auch, sollte ich in der Lage sein zu sehen, die die Werte der bind-Variablen?
UPDATE: ich rufe updateFromForm() innerhalb des Controllers:
@RequiresAuthentication(clientName = "FormClient")
public static Result updateProfile() throws Exception {
final CommonProfile profile = getUserProfile();
String email = getEmail(profile);
Person p = Person.find.where().eq("email", email).findList().get(0);
Map<String, String[]> form = request().body().asFormUrlEncoded();
if (p == null) {
Person.createFromForm(form);
} else {
p.updateFromForm(form);
}
return ok("HI");
}
- Könnte man auch die Methode, wobei Sie aufrufen
updateFromForm
? - Ok, ich aktualisiert. Ich nenne updateFromForm() in einem controller. updateFromForm selbst definiert ist, in einem Modell. Weißt du, - soll ich die Werte für die bind-Variablen in meiner Fehlermeldung oder nicht? Vielen Dank für jede Hilfe.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bisschen spät, aber für Ihren Fall
@Version
annotation sollte die Lösung sein. Wir verwenden es hauptsächlich mitjava.util.Date
, so kann es ebenfalls verwendet werden, um festzustellen, das Datum der letzten Datensatz-Aktualisierung im Play-Modell, das ist einfach:In diesem Fall update-Anweisung erledigt wird mit
id
undversion
Felder nur - nützlich, vor allem beim Einsatz mit großen Modellen:Hinweis: Sie brauchen nicht/sollte das update hier auch manuell bei jedem speichern, Ebean tut es selbst.
version
- Wert ändert sich NUR, wenn es aktualisiert die Daten (also mitobj.update()
wo sich nichts ändert nicht aktualisierenversion
Feld)@javax.persistence.Version
ansonsten neue Frage und zeigen Sie uns Ihr Modell.Habe ich einen alternativen Ansatz zu diesem, wo ich die Anmerkung
um die Entity-Klasse.
Dies deaktiviert das optimistische sperren gleichzeitige Modifikation check Bedeutung die SQL wird
Dies ist sogar noch optimistischer, da es einfach überschreibt alle zwischenzeitlichen Veränderungen.
Rätsel gelöst.
Erstens - das public service announcement. "OptimisticLockException" ist ein großer Eimer. Wenn Sie versuchen, die Spur einer diese nach unten offen sein für die Idee, es könnte wirklich alles sein.
Dachte ich, mein problem von dumping-SQL-log und Suche nach diesem:
Also ich denke, was passiert, wenn Sie ein update ist, dass es baut eine WHERE-Klausel mit allen bekannten Einheiten und Ihre Werte, als Sie ursprünglich bereit.
Dass heißt, wenn in irgendeinem anderen Teil Ihres Codes oder einem anderen Prozess ändert sich etwas hinter Ihr zurück, diese Abfrage fehl. Ich habe zu Unrecht angenommen, dass das problem war, dass irgendwie .setName('Bob') hatte, änderte sich der name in der DB oder einem Objekt-cache.
Wirklich, was passiert war, ist, dass die WHERE-Klausel enthält ein Datum, während meine Datenbank umfasst eine ganze timestamp mit Datum, Uhrzeit und Zeitzone.
Jetzt hab ich behoben, indem man einfach auskommentieren der timestamp in das Modell, bis ich herausfinden kann, ob/wie Ebean kann mit diesen Daten geben.
Ich hatte das gleiche problem,
nach Stunden der Suche habe ich den Grund gefunden..
Es war der Inkonsistenz die Parameter-Typ in der Datenbank (in meinem Fall string) und das Objekt das ich erstellt und versucht Sie zu retten-java.util.Datum.
nach der änderung der Datenbank zu halten datetime-Objekt, das problem war gelöst