NEW: CustomDeployParser

This commit is contained in:
Jonas Pöhler committed 2021-10-22 15:04:46 +02:00
1 parent 60cf9fa078
commit 50824f1d7f
15 files changed
+287 -6

No files matched your search

@@ -0,0 +1,61 @@
package org.tests.model.tevent;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import io.ebean.annotation.Formula;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.plugin.CustomDeployParser;
import io.ebean.plugin.DeployBeanDescriptorMeta;
import io.ebean.plugin.DeployBeanPropertyMeta;
import io.ebean.util.AnnotationUtil;
import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocMany;
/**
* Custom Annotation parser which parses @Count annotation
*
* @author Roland Praml, FOCONIS AG
*/
public class CustomFormulaAnnotationParser implements CustomDeployParser {
private int counter;
@Target(FIELD)
@Retention(RUNTIME)
@Formula(select="TODO", join = "TODO") // meta-formula
public @interface Count {
String value();
}
@Override
public void parse(final DeployBeanDescriptorMeta descriptor, final DatabasePlatform databasePlatform) {
for (DeployBeanPropertyMeta prop : descriptor.propertiesAll()) {
readField(descriptor, prop);
}
}
private void readField(DeployBeanDescriptorMeta descriptor, DeployBeanPropertyMeta prop) {
Count countAnnot = AnnotationUtil.get(prop.getField(), Count.class);
if (countAnnot != null) {
// @Count found, so build the (complex) count formula
DeployBeanPropertyAssocMany<?> countProp = (DeployBeanPropertyAssocMany<?>) descriptor.getBeanProperty(countAnnot.value());
counter++;
String tmpTable = "f"+counter;
String sqlSelect = "coalesce(" + tmpTable + ".child_count, 0)";
String parentId = countProp.getMappedBy() + "_id";
String tableName = countProp.getBeanTable().getBaseTable();
String sqlJoin = "left join (select " + parentId +", count(*) as child_count from " + tableName + " GROUP BY " + parentId + " )"
+ " " + tmpTable + " on " + tmpTable + "." +parentId + " = ${ta}." + descriptor.idProperty().getDbColumn();
prop.setSqlFormula(sqlSelect, sqlJoin);
// prop.setSqlFormula("f1.child_count",
// "join (select parent_id, count(*) as child_count from child_entity GROUP BY parent_id) f1 on f1.parent_id = ${ta}.id");
}
}
}
@@ -41,6 +41,11 @@ public class TEventOne {
@OneToMany(mappedBy = "event", cascade = CascadeType.ALL)
List<TEventMany> logs;
@CustomFormulaAnnotationParser.Count("logs")
//@Formula(select = "f1.child_count",
//join = "left join (select event_id, count(*) as child_count from tevent_many GROUP BY event_id ) as f1 on f1.event_id = ${ta}.id")
Long customFormula;
public TEventOne(String name, Status status) {
this.name = name;
this.status = status;
@@ -63,6 +68,10 @@ public class TEventOne {
return count;
}
public Long getCustomFormula() {
return customFormula;
}
public Double getTotalUnits() {
return totalUnits;
}
@@ -48,7 +48,7 @@ public class TestAggregationCount extends BaseTestCase {
List<TEventOne> list = query.findList();
String sql = sqlOf(query, 5);
assertThat(sql).contains("select t0.id, t0.name, t0.status, t0.version, t0.event_id from tevent_one t0");
assertThat(sql).contains("select t0.id, t0.name, t0.status, coalesce(f1.child_count, 0), t0.version, t0.event_id from tevent_one t0");
for (TEventOne eventOne : list) {
// lazy loading on Aggregation properties