Hi Rob, this sounds great. Generics support is really welcome, as well as even lazier loading.
I see you are still using the MapBeans for results. While that works well, isn't it possible to map MapBeans automatically to @Entity objects? (or maybe another or extra annotation for those beans like @QueryResult). After all, all the data is there in the bean on how to map the results. It would also be very nice to be able to predefine queries just once, instead of having to create new instances with a constant string. This would also make it possible to reuse and/or preconfigure them.
I've been brainstorming a bit about this, maybe you can use it. Please don't trip over the syntax, it's more about the idea.
The most transparant way for this to work, is if a query result entity is defined just like a normal table entity. It would need some added annotation. I was thinking in the line of:
@Entity
@QueryResult(query="find order(id) join customer(name) where customer.birthdate after :birthDate limit 10")
public class ReportLine {
int id;
@Column(name="name") String customerName;
}
The user could then fetch it like any other object, but using properties instead. For instance:
List ReportLine report = EBeans.find(ReportLine.class, birthDate [, ... , ... ]);
Or, to set named properties, the user would have to fetch the queryproperties first and set them:
QueryProperties props = Report.newParams();
params.add("birthDate", birthDate)
params.add ... etc
List ReportLine report = EBeans.find(ReportLine.class, params);
or, shorthand:
List ReportLine report = EBeans.find(ReportLine.class, Report.newParams().add("birthDate", birthDate));
As you see I separated the query properties from the query, so the query itself can remain static and final. The nice thing about this is that you can also specify your own property setter this way and enforce that queries can not be passed non existing or bad parameters, and the whole thing also becomes more refactorable. I imagine something like this:
@Entity
@QueryResult ReportQueryProps (query="find order(id) join customer(name) where customer.birthdate after :birthDate limit 10")
public class ReportLine {
int id;
@Column(name="name") String customerName;
}
public class ReportQueryProps extends QueryProperties {
public boolean isValid() {
// can add more checks
return get("birthDate") != null;
}
public ReportQueryProps setCustomer(Customer cust) {
add("birthDate", cust.getBirthDate());
// ... etc
}
}
Now a query can be done like this:
List ReportLine report = EBeans.find(ReportLine.class, Report.newParams().setCustomer(customer));
Damn I really spilled my brains here, but, you asked for it ;-) Hope it helps!
Best regards,
Christian