Beim Migrieren einer vorhandenen App von Grails 2.5 auf 3.1 stieß ich auf ein seltsames Problem mit einer bidirektionalen Eins-zu-Eins-Beziehung.Grails 3 hasOne nullability-Problem
Stellen Sie sich ein einfaches Modell mit einem Benutzer und Employee
Objekte vor. Ein User
repräsentiert ein generisches Benutzerkonto. Nicht alle Benutzer sind Mitarbeiter, aber alle Mitarbeiter sind Benutzer. Darüber hinaus haben Mitarbeiter Referenzen auf Manager, Supervisor usw. (auch User-Instanzen). Benutzer ist die besitzende Seite der Beziehung.
class User {
Employee employee
static mappedBy = [employee: "user"]
static hasOne = [employee: Employee]
static constraints = {
employee(nullable:true)
}
}
class Employee {
User user // represents employee's own account, a bi-directional one-to-one
User supervisor // represents a supervisor
static belongsTo = [user: User]
static constraints = {
user(unique:true)
supervisor(nullable:true)
}
}
Das Problem nach dem Upgrade 3 bis Grails ist, dass der Modus erzeugen in diesem in supervisor_id
Spalte von Tabelle employee als NOT NULL
wobei ergibt erzeugt, wohingegen in Grails 2 es NULL festlegbaren wie erwartet war (nur mit NOT NULL user_id).
Ich habe dies mit Grails 3.1.12 und 3.2.0 getestet, das gleiche Verhalten mit beiden erhalten. Mache ich irgendetwas Dummes in meinen Domain-Klassen-Deklarationen? Ich habe mehrere Mappings ausprobiert, um ohne Glück dasselbe Verhalten wie in Grails 2.5 zu erreichen. In einigen Fällen bekomme ich sogar einen Fremdschlüssel auf beiden Seiten der Beziehung ...
Vielen Dank für Ihre Antwort! Ich habe Ihren Code in Grails 3.2.0 versucht, aber es führt immer noch dazu, dass der Spalte supervisor_id der Tabelle employee ein NOT NULL hinzugefügt wird, trotz der Bedingung nullable: true. Wie bei dem Objekt "mappedBy on" ist dies ein Link von älterem Code, bei dem die Eins-zu-Eins-Zuordnung optional war und die Eigentümerseite umgekehrt war (der Fremdschlüssel war jedoch immer auf der Benutzerseite). – Rado
Die wichtige Sache, die zu beachten ist, ist, dass Grails selbst die Nullable-Einschränkung (sogar mit meinem ursprünglichen "schlechten" Code) berücksichtigt. Wenn Sie also gegen ein vorhandenes oder manuell erstelltes Datenbankschema laufen, funktioniert es wie erwartet. Aber es ist das hbm2ddl-Schema, das falsch generiert wird, wenn auf diese Spalten NOT NULL angewendet wird, und dies bricht unsere Integrationstests, die mit einer In-Memory-H2-Datenbank ausgeführt werden. – Rado
Gern geschehen. Ich werde versuchen, es in ein paar Stunden zu reproduzieren und werde Sie wissen lassen. – quindimildev