2016-07-14 22 views
0

Ich verwende in einem meiner Projekte ormlite und ich habe eine Klasse A mit einem Feld f von benutzerdefinierten Typ F und ich habe die Anforderung, dass Feld f in keiner null sein sollte Fall. Deshalb möchte ich ein neues Objekt der Klasse F instanziiert, wenn das Feld f in der Datenbankdatei NULL istGriff NULL Fall innerhalb sqlArgToJava von benutzerdefinierten persister Klasse

class A { 
    @DatabaseField(columnName = "xyz", persisterClass = FieldPersister.class) 
    F f; 

    public A() { 
     f = new F(); 
    } 
} 

sich nach den docs ich eine benutzerdefinierte persister-Klasse FieldPersister und eine Null-Check-in dort versucht.

class FieldPersister extends StringType { 
    public Object javaToSqlArg(FieldType fieldType, Object javaObject) { 
     ... 
    } 

    public Object sqlArgToJava(FieldType fieldType, Object sqlArg, int columnPos) { 
     if (sqlArg == null) return new F(); 
     else { 
      String value = (String) sqlArg; 
      return new F(value); 
     } 
    } 
} 

Ich habe versucht, das Programm Debuggen und sah, dass es bereits eine Nullprüfung in dem folgenden Verfahren

resultToJava(FieldType fieldType, DatabaseResults results, int columnPos) 

Auch zwingende diese Methode nicht das Problem behoben hat, die auf meine Frage führt, ist Wie kann ich mit dieser Situation umgehen, oder fehlt mir ein Teil des Puzzles?

Aktualisierung mit SSCCE:

pom.xml

Main.java

StringPropertyPersister.java

+1

Ich habe den Beitrag mit einem Testprogramm aktualisiert, sehen, ob es hilft. – calvin

Antwort

0

Auch zwingende diese Methode nicht das Problem behoben hat, die zu meiner Frage führt, ist es eine Möglichkeit, Handle mit dieser Situation oder fehlt mir ein Teil des Puzzles?

Sie vermissen einen Teil des Puzzles und es ist ziemlich subtil. Leider gibt die Methode ResultSet.getInt(...) eine int zurück. Warum ist das wichtig? Weil ORMLite nicht erkennen kann, ob das Feld in der Datenbank NULL ist oder nicht, wenn es ein Primitiv ist. In der Regel kommt es vor, dass ORMLite ein Ergebnis von ResultSet erhält, fragt, ob es vom benutzerdefinierten Konverter konvertiert wird, und ORMLite sieht, ob es null ist, und passt den Wert entsprechend an. Vielleicht gibt es bessere Möglichkeiten, das zu tun. Ich muss darüber nachdenken.

Sie haben hier ein paar Lösungen.

  1. eine defaultValue = "" auf die Definition des Feldes hinzufügen. Dies wird nicht den Fall behandeln, wenn NULL Wert auf der Festplatte ist, aber es funktioniert, wenn Sie dao.create(...) verwenden. Sie können dann FieldConverter.parseDefaultString(...) verwenden, um das einzufügende Standardobjekt zu definieren, wenn das Feld null ist.

  2. In Ihrer A.getValue() Methode, tun Sie den null Scheck dort und ein new SimpleStringProperty("") zurück, wenn es null ist. Aber dann könnte Ihr Beispielcode zu einfach sein.

  3. Der Hack ist sowohl die resultToJava(...) Methode außer Kraft zu setzen, um so etwas wie:

    @Override 
    public Object resultToJava(FieldType fieldType, DatabaseResults results, 
         int columnPos) throws SQLException { 
        // remove the null check here so we can handle the null 
        Object value = resultToSqlArg(fieldType, results, columnPos); 
        return sqlArgToJava(fieldType, value, columnPos); 
    } 
    

    Aber Sie müssen auch die folgende außer Kraft zu setzen, die ein Hack ist.

    @Override 
    public boolean isStreamType() { 
        // this forces the null check to be ignored 
        return true; 
    } 
    

    Dies ist ein Hack, denn wenn ORMLite ändert subtil die Art und Weise es „Strom“ SQL-Typen behandelt, es Ihren Code brechen könnte.

    Siehe meine Version Ihres Tests hier: CustomFieldNullTest.java.

+0

Danke! es funktionierte. Ich habe die 3. Lösung verwendet, da ich bereits 'NULL' auf der Festplatte gespeichert habe. – calvin