Ormlite:使用generic作为id的类型

时间:2012-03-23 16:49:34

标签: java database generics ormlite

我在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);
    }

}

当然没有工作......

有谁知道如何解决这个问题?谢谢!

1 个答案:

答案 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);
}