我在java中使用ormlite进行数据库交互。工作正常。
现在我想创建一个通用实体类。也许我会从一些代码开始解释它。
AbstractId类似于所有ID的基类:
public abstract class AbstractId {
public AbstractId(String id) {
this.id = id;
}
public String value() {
return this.id;
}
}
扩展为:
public class SampleId extends AbstractId {
public SampleId(String id) {
super(id);
}
}
现在我有一个抽象的基本实体来保存一些输入;)
public abstract class AbstractEntity<T> {
@DatabaseField(id = true, columnName = "id")
private T id;
@DatabaseField(columnName = "name", canBeNull = false)
private String name;
public AbstractEntity() {
}
}
由示例实体扩展:
@DatabaseTable(tableName = "sample")
public class SampleEntity<T extends AbstractId> extends AbstractEntity<T> {
@DatabaseField(canBeNull = false, columnName = "key")
private String otherValue;
public SampleEntity() {
}
}
那我怎么能坚持T?实体实例由
创建SampleEntity<SampleId> entity = new SampleEntity<>() // (*)
我尝试创建一个新的BaseDataType并设置DatabaseField以将其用作persisterClass:
public class AbstractIdPersister extends BaseDataType {
public AbstractIdPersister(SqlType sqlType, Class<?>[] classes) {
super(sqlType, classes);
}
@Override
public Object parseDefaultString(FieldType fieldType, String defaultStr)
throws SQLException {
return null;
}
@Override
public Object javaToSqlArg(FieldType fieldType, Object obj) {
AbstractId abstractId = (AbstractId) obj;
return abstractId.value();
}
@Override
public Object sqlArgToJava(FieldType fieldType, Object sqlArg, int columnPos)
throws SQLException {
// HOW DO I GET THE GENERIC TYPE DEFINED ABOVE (*)
}
@Override
public Object resultToSqlArg(FieldType fieldType, DatabaseResults results,
int columnPos) throws SQLException {
return results.getString(columnPos);
}
}
当然没有工作......
有谁知道如何解决这个问题?谢谢!
答案 0 :(得分:1)
因此,鉴于您的层次结构,ORMLite在需要从关联的数据库字段创建抽象类的实例时会遇到问题。这就是sqlArgToJava
方法试图做的事情。例如,在DATE_LONG
类型中,日期以很长的时间毫秒存储在数据库中,因此sqlArgToJava
方法是:
public Object sqlArgToJava(FieldType fieldType, Object sqlArg, int columnPos) {
// create a Date object
return new Date((Long) sqlArg);
}
显然无法创建AbstractId
的实例。您将不得不为每个子类创建一个容器。
如果你善于反思那么你可以做类似下面的事情,但这肯定是一个黑客。我认为为每个具体类创建一个持久性是可行的方法。
try {
// find the type of the field, and look for a String constructor
return fieldType.getType().getConstructor(String.class).newInstance(sqlArg);
} catch (Exception e) {
throw SqlExceptionUtil.create("could not call the string constructor on "
+ fieldType.getType(), e);
}