2016-05-31 8 views
0

Gegeben:GORM domain.delete (flush: true) nicht feuern HibernateException noch andere Rückmeldungen?

Foo() { 
    Bar bar 

    static contraints = { 
     bar (nullable: false) 
    } 
} 

und ein Service-Bar-Typen zu verwalten, wo eine Methode löscht:

line 105: BarService { 
line 106:  public BarCommand deleteBar(long Id) {  
line 107:   Bar b = Bar.get(Id) 
line 108:   if (!b.delete(flush: true)) { 
line 109:    //handle error here 

wenn es bereits ein Foo ist, "f", die bereits eine Bar von id hat 1 (Zum Beispiel sollte Zeile 108 mit einem Fehler fehlschlagen, der erklärt "b kann nicht gelöscht werden, es wird Foo id: 1 zugewiesen", aber alles, was passiert, ist Zeile 108 gibt false auf Wahrheit zurück und fällt in die Fehlerbehandlung ob das Löschen erfolgreich war oder nicht.

Woher wissen wir, wenn wir eine Domain löschen, ob das Löschen erfolgreich war oder fehlgeschlagen ist? die doco bedeutet dies nicht beschreiben - Hibernate berichtet, dass ein HibernateException abfeuern sollte, aber keine Ausnahmen werden in jeder Einheit Testszenario gefeuert ...

(http://docs.grails.org/latest/ref/Domain%20Classes/delete.html)

I domain.delete erkennen() würde nichts zurück Da das Löschen nicht bis zu einem Flush-Ereignis an die Datenbank kommuniziert wird, dachte ich, dass ich explizit flush aufrufen würde: true würde dies ansprechen, aber es scheint nicht so zu sein.

+1

Ich bekomme eine org.h2.jdbc.JdbcSQLException, wenn ich das versuche. Hast du Grails die DB erstellen lassen? Gibt es eine Fremdschlüsseleinschränkung zwischen den beiden Tabellen? Verletzung der referenziellen Integritätsbedingung: "FK_L4JFPMMT6FPXP3BI37GJ26SFD: PUBLIC.FOO FREMDSCHLÜSSEL (BAR_ID) REFERENCES PUBLIC.BAR (ID) (1)"; SQL-Anweisung: Löschen aus der Leiste mit ID =? und Version =? [23503-191] – billjamesdev

+0

Nein, sie lassen Grails ihren DB nicht bauen, und ja, es gibt ein FK-Setup, das verletzt werden sollte. Oohh - vielleicht muss dieser Test als Integration und nicht als Einheit laufen? Ich werde es morgen versuchen müssen. – Gr3go

Antwort

1

Persönlich mag ich die Ineffizienz der ein Objekt aus der DB für den alleinigen Zweck Abrufen sie zu löschen, so statt dessen:

Bar b = Bar.get(Id) 
if (!b.delete(flush: true)) { 
    // handle error here 
} 

Ich würde HQL verwenden das Löschen durchzuführen, da dies die Notwendigkeit vermeidet rufen Sie es zuerst (die load() Methode ist eine alternative Lösung).

Integer rowsDeleted = Bar.executeUpdate('delete Bar where id = ?', [Id]) 
if (!rowsDeleted) { 
    // handle error here 
} 

Ein weiterer Vorteil dieses Ansatzes besteht darin, dass executeUpdate die Anzahl der Zeilen zurück, aktualisiert/gelöscht, so dass Sie, ob die Operation erfolgreich war überprüfen.

+0

Einverstanden, aber wir tun dies, um zu melden, ob ein Objekt für eine gegebene ID gefunden wurde. In diesem Fall mag ich Ihre HQL-Lösung. Ich gehe einfach zu einem Integrationstest. – Gr3go