简体   繁体   中英

ActiveJDBC and Java Generics causing

I have the following two classes, where the Document extends an Abstract class that provides helper functions, one of which is a "find" method that builds queries to find records based on some simple logic.

public abstract class AbstractTable<T extends AbstractTable<T>> extends Model {
  ...
    public T find (String[] columns) {
        String whereClause = "";
        List<Object>    whereClauseData = new ArrayList<Object> ();

        for (String column : columns) {
            Object  data = this.get(column);
            if (data == null) {
                whereClause += column + " is null AND ";
            } else {
                whereClause += column + " = ? AND ";
                whereClauseData.add (data);
            }
        }

        return findFirst (whereClause.substring(0, whereClause.length () - 5), whereClauseData.toArray());
    }
}


public class Document extends AbstractTable<Document> { 
...
    public Document findExistingObject(Document document) {
        String[] columns = new String[] {"court_case_id", "number", "name", "file_date"};
        return super.find (columns);
    }
}

When I run this code, and the "findExistingObject" method is called on a Document, I receive this exception:

Exception in thread "main" org.javalite.activejdbc.InitException: failed to determine Model class name, are you sure models have been instrumented?

I've made completely sure that I've instrumented the classes. When I move the code from AbstractTable into Document, everything works perfectly. I'm hoping someone can lend some advice, or help, that might show me what I'm doing wrong.

Thanks in advance.

The exact reason for your issue is not generics, but instrumentation. Instrumentation skips abstract models, which means that the method findFirst is called on class Model , and not on Document . You need to invoke a method findFirst on the model Document . Here is a version of code that will work for you:

public T find (String[] columns) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    String whereClause = "";
    List<Object> whereClauseData = new ArrayList<>();

    for (String column : columns) {
        Object  data = get(column);
        if (data == null) {
            whereClause += column + " is null AND ";
        } else {
            whereClause += column + " = ? AND ";
            whereClauseData.add (data);
        }
    }

    Method findFirst = getClass().getDeclaredMethod("findFirst", String.class, Object[].class);
    return (T) findFirst.invoke(null, whereClause.substring(0, whereClause.length () - 5), whereClauseData.toArray());
}

There is a bit of ugliness there, but at least you can apply this across all your models (if this is what you want).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM