I’m using ormlite for database interaction in java. Works fine.
Now I want to create a generic entity class. Perhaps I’ll start with a bit of code to explain it.
AbstractId is something like a base class for all ids:
public abstract class AbstractId {
public AbstractId(String id) {
this.id = id;
}
public String value() {
return this.id;
}
}
Extended to:
public class SampleId extends AbstractId {
public SampleId(String id) {
super(id);
}
}
Now I have a abstract base entity to save some typing 😉
public abstract class AbstractEntity<T> {
@DatabaseField(id = true, columnName = "id")
private T id;
@DatabaseField(columnName = "name", canBeNull = false)
private String name;
public AbstractEntity() {
}
}
which is extended by a sample entity:
@DatabaseTable(tableName = "sample")
public class SampleEntity<T extends AbstractId> extends AbstractEntity<T> {
@DatabaseField(canBeNull = false, columnName = "key")
private String otherValue;
public SampleEntity() {
}
}
So how can i persist T? The entity instance is created by
SampleEntity<SampleId> entity = new SampleEntity<>() // (*)
I tried to create a new BaseDataType and setting the DatabaseField to use this as 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);
}
}
Didn’t work … of course..
Does anyone has any idea how to solve this problem? Thank you!
So given your hierarchy, ORMLite is going to have a problem when it needs to create an instance of your abstract class from the associated database field. That’s what the
sqlArgToJavamethod is trying to do. In theDATE_LONGtype, for example, the date is stored in the database as a long time milliseconds, so thesqlArgToJavamethod is:Obviously there is no way to create an instance of
AbstractId. You are going to have to make a persister for each of the subclasses instead.If you are good with reflection then you could do something like the following but it’s a hack for sure. I think creating a persister for each of your concrete classes is the way to go.