2013-10-11 5 views
7

Ich habe zwei Zeilen in MySQL wie dieseSo verwenden Hibernate eqOrIsNull()

+---------+---------+ 
| foo  | bar  | 
+---------+---------+ 
|   | NULL | 
|   |   | 
+---------+---------+ 

Wo leer sind leere Strings "".

Jetzt möchte ich beide bekommen. Ich verwende Criteria und Restrictions.eqOrIsNull() für beide Spalten, aber es gibt immer nur eine Zeile zurück.

Der Code ist wie diese

criteria.add(Restrictions.eqOrIsNull("foo", "")); 
     .add(Restrictions.eqOrIsNull("bar", "")); 

Und wenn ich Kriterien hinzufügen nur auf foo, gibt es zwei Reihen. Aber für bar gibt es nur die Sekunde zurück, die leer ist.

Die javadoc sagt, Apply an "equal" constraint to the named property. If the value is null, instead apply "is null". Also bekomme ich das falsch, oder sollte es auf andere Weise verwendet werden?

UPDATE:
Sorry, ich bin so sorglos. Der Doc sagt es deutlich. Diese Methode arbeitet nach dem übergebenen value, nicht dem tatsächlichen Wert der in der DB gespeicherten benannten Eigenschaft.
Quellcode auf Github:

public static Criterion eqOrIsNull(String propertyName, Object value) { 
    return value == null 
      ? isNull(propertyName) 
      : eq(propertyName, value); 
} 

Also in meinem Fall eqOrIsNull kehrt eq(""). Ich hätte die Disjunktion von und isNull, wie Gregory answered verwenden sollen.

+1

Für diese Art von Problemen sollten Sie Debug-Protokollierung aktivieren. Es wird Hibernate print die ausführende SQL machen. – adam0404

+0

Es ist wie 'wählen foo, bar aus der Tabelle wo foo =? und bar =? ' – hsluo

Antwort

2

Überprüfen Sie, ob dieser Code tut, was Sie wollen -

criteria.add(Restrictions.or(Restrictions.eq("foo", ""), Restrictions.isNull("foo"))) 
       .add(Restrictions.or(Restrictions.eq("bar", ""), Restrictions.isNull("bar"))); 

Dieser Code-Schnipsel verwendet Hibernate 3.5.0-CR-2-API.

+0

Es funktioniert in diesem Fall, aber wenn eine Spalte nicht leeren Inhalt hat, wird es auch bekommen. – hsluo

+0

Gotcha, siehe aktualisierte Antwort. –

+2

Dieser funktioniert ... können Sie erklären, warum sich das von 'eqOrIsNull()' unterscheidet? Ich benutze Hibernate 4.2.5. – hsluo

2

Wenden Sie eine "gleiche" Einschränkung auf die benannte Eigenschaft an. Wenn der Wert null ist, wenden Sie stattdessen "is null" an.

Dies bedeutet, is null wird nur angewendet, wenn NULL als Wert übergeben wird. Wenn Sie eine andere Zeichenfolge als Wert angeben, wird nur equal für diesen Wert angewendet.

Dies ist nützlich, wenn Sie sich nicht sicher sind, ob der tatsächliche Wert zur Laufzeit als Argument für den Parameterwert übergeben wird. In einem solchen Szenario, auf eine traditionelle Weise, müssen Sie entweder eine Null-Überprüfung & schreiben Kriterien basierend auf der Bedingung nicht null oder Sie müssen Kriterien in der Art und Weise schreiben, wie von Gregory's Antwort erwähnt.

Halten Sie all diese Fakten im Hinterkopf, sollten Sie die Antwort auf Ihre Frage erhalten. Sie erhalten nur die Zeilen, die den leeren Wert & enthalten, nicht den, der den Wert NULL hat, weil Sie als Argument eine leere Zeichenfolge angegeben haben. Wenn Sie NULL als zweites Argument angeben, erhalten Sie nur die Zeilen mit dem NULL-Wert.

Lassen Sie mich wissen, ob das für Sie hilfreich ist.

+0

Danke für die Erklärung. Ich habe das Dokument und den Quellcode gelesen und mein Problem gefunden. Siehe mein Update. – hsluo