我在我的某个项目中使用了ormlite,并且我有一个类A
,其字段为f
自定义类型F
,我要求字段{{1}在任何情况下都不应为null。因此,只要数据库文件中的字段f为NULL,我就想实例化F类的新对象
f
根据我使用自定义持久化类class A {
@DatabaseField(columnName = "xyz", persisterClass = FieldPersister.class)
F f;
public A() {
f = new F();
}
}
并尝试在那里进行空检查的文档。
FieldPersister
我尝试调试程序,发现以下方法已经存在空检查
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);
}
}
}
即使重写这种方法也没有解决导致我的问题的问题,有没有办法处理这种情况或者我错过了一些难题?
使用SSCCE更新:
答案 0 :(得分:0)
即使重写这种方法也没有解决导致我的问题的问题,有没有办法处理这种情况或者我错过了一些难题?
你错过了谜题的一部分而且非常微妙。不幸的是,ResultSet.getInt(...)
方法返回int
。为什么这很重要?因为ORMLite无法判断数据库中的字段是否为NULL
,如果它是原语。所以通常会发生的事情是ORMLite从ResultSet
获取结果,要求它由自定义转换器转换,然后ORMLite查看它是否为null并适当调整该值。也许有更好的方法来做到这一点。我需要考虑一下。
这里有几个解决方案。
在您的字段定义中添加defaultValue = ""
。如果磁盘上存在NULL
值,则无法处理此情况,但如果您使用dao.create(...)
,则该值将起作用。然后,如果该字段为空,则可以使用FieldConverter.parseDefaultString(...)
来定义要插入的默认对象。
在A.getValue()
方法中,您在那里进行null
检查,如果为空则返回new SimpleStringProperty("")
。但是,你的示例代码可能过于简单了。
黑客攻击是将resultToJava(...)
方法覆盖为:
@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);
}
但你还需要覆盖以下哪个是黑客。
@Override
public boolean isStreamType() {
// this forces the null check to be ignored
return true;
}
这是一个hack,因为如果ORMLite巧妙地改变它处理“流”SQL类型的方式,它可能会破坏你的代码。
在此处查看我的测试版本:CustomFieldNullTest.java。