I've been playing around with getting rid of DAOs in favor of ActiveRecord like entities in Java, but generics won't allow me to have the full functionality that I want (like static finders). Somehow Groovy does, but I'm confused why. Given the following:
class ActiveRecord<T> {
static Class<T> genericType;
ActiveRecord() {
genericType = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
static T find(Serializable id) { return EntityManagerHolder.find(genericType, id); }
void save() { EntityManagerHolder.persist(this); }
}
@Entity @Table(name="TEST")
class FakeTable extends ActiveRecord<FakeTable> {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
Long id;
String status;
String type;
static void main(args) {
FakeTable t = new FakeTable();
t.status = "TESTING";
t.save();
println FakeTable.find(t.id);
}
}
This code works (with the JPA stuff that's excluded), but I'm not sure why I'm able to declare
static Class<T> genericType;
Does the compiler do some magic before the actual Java class is compiled? Maybe the groovy compiler is replacing T with the actual class name in the generated Java class?
In strictly Java, I can access the generic type from the find method return type and the class declaration, but both are erased to Object. That makes sense, and Groovy does the same, but in Java, the above line errors out with a message similar to 'Cannot reference non-static T'.