Ich musste Spring von 1.2.7 auf 2.0 aktualisieren, ebenso Grails von 2.2.0 bis 2.3.11 . Nachdem ich ein paar typische Update-Probleme gelöst hatte, fing ich an, einen WAR für den Testserver zu erstellen. Alles schien in Ordnung zu sein. Aber nach ein paar Bereitstellungen stieß ich auf ein Problem.
Manchmal (es gibt keine Regel) hat der Server 100% CPU-Auslastung - & gt; OutOfMemeryError oder die Anwendung löst den Fehler 500 aus. Nach dem Debugging habe ich festgestellt, dass der Grund für diese Probleme eine falsche SQL-Abfrage ist.
Wo Frage:
%Vor%erstellt solche SQL:
%Vor%und hier das richtige SQL:
%Vor%Das offensichtliche Problem ist, dass Ausdruck "(1 = 1 und 1 = 1)" . In der Tat, eine solche Abfrage:
%Vor%ruft die gesamte Tabelle ab. Dynamische Finder oder Kriterien verursachen dieses Problem nicht.
Ich habe zwei Leute gefunden, die ein ähnliches Problem hatten:
Plugins, die ich verwende:
Datenbank: PostgreSQL 8.4.20
Ich habe viele Lösungen ausprobiert:
Nach dem, was ich oben in einem Blog gelesen habe, schrieb Graeme Rocher, dass das Problem möglicherweise auf einen Mangel an GORM in der Anwendung zurückzuführen ist. Allerdings war das Problem während des Aufbaus von WAR - Abhängigkeiten wurden falsch gepackt (?). Aber hier tritt das Problem auf, wenn WAR entpackt oder wenn Klassen geladen werden. Ein Blick auf die Quelle des Problems aus dem Blogeintrag zeigt, dass das Problem möglicherweise auf einen lächerlichen Grund zurückzuführen ist ...
Hat jemand eine Idee, was dieses Problem verursachen könnte oder was kann ich debuggen, um die Quelle des Fehlers feststellen zu können? Und die Frage an grails dev: Was hat sich zwischen Version 2.2 und 2.3 geändert, die theoretisch ein solches Problem verursachen könnte?
Das Problem scheint von AbstractHibernateCriterionAdapter
im grails-datastore-gorm-hibernate-core
JAR zu kommen.
Die criterionAdaptors
HashMap ist nicht richtig ausgefüllt.
Diese Karte ist ein final static HashMap
, das verwendet wird, um GORM-Kriterien auf Hibernate-Einsen abzubilden.
Das Problem tritt zufällig auf, wenn die Anwendung gestartet wird.
Manchmal wird die HashMap ohne Probleme ausgefüllt, manchmal tritt ein Problem auf
Diese Hashmap ist static final
und wird für den Rest der Anwendungslebensdauer beschädigt. Deshalb stößt man irgendwann auf dieses Problem und nach einem Neustart läuft alles gut.
Die HashMap kann beschädigt werden, wenn mehrere Threads gleichzeitig ein AbstractHibernateCriterionAdapter
-Objekt erstellen.
Jeder Thread ruft den Konstruktor und die Methode initialize()
auf.
Diese Methode ist synchronized
, aber das synchronized
idiom ist nur für mehrere Threads wirksam, die auf das selbe Objekt zugreifen ( Ссылка )
Als Ergebnis blockiert die synchronized
die initialize()
-Methode nicht richtig und mehrere Threads können versuchen, die criterionAdaptors
HashMap zur gleichen Zeit zu füllen.
HashMap
ist nicht threadsicher, da ein Ergebnis die HashMap wird beschädigt und einige Kriterien fehlen.
Wenn in dieser HashMap kein GORM-Kriterium gefunden wird, wird das Kriterium still ignoriert ... Das erklärt, warum es aus der generierten Anforderung verschwindet.
Ich habe ein Github-Problem erstellt: Ссылка
Es ist eine seltsame Art und Weise, alle Instanzen des Benutzers auf diese Weise durch die ID zu erhalten.
Haben Sie das versucht?
%Vor%Tags und Links hibernate grails gorm grails-2.3