mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
NEW: CustomDeployParser
This commit is contained in:
@@ -16,6 +16,7 @@ import io.ebean.event.changelog.ChangeLogPrepare;
|
||||
import io.ebean.event.changelog.ChangeLogRegister;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.plugin.CustomDeployParser;
|
||||
import io.ebean.util.StringHelper;
|
||||
|
||||
import javax.persistence.EnumType;
|
||||
@@ -389,6 +390,7 @@ public class DatabaseConfig {
|
||||
private List<BeanQueryAdapter> queryAdapters = new ArrayList<>();
|
||||
private final List<BulkTableEventListener> bulkTableEventListeners = new ArrayList<>();
|
||||
private final List<ServerConfigStartup> configStartupListeners = new ArrayList<>();
|
||||
private final List<CustomDeployParser> customDeployParsers = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* By default inserts are included in the change log.
|
||||
@@ -2674,6 +2676,17 @@ public class DatabaseConfig {
|
||||
return configStartupListeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a CustomDeployParser.
|
||||
*/
|
||||
public void addCustomDeployParser(CustomDeployParser customDeployParser) {
|
||||
customDeployParsers.add(customDeployParser);
|
||||
}
|
||||
|
||||
public List<CustomDeployParser> getCustomDeployParsers() {
|
||||
return customDeployParsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all the BeanPersistListener instances.
|
||||
* <p>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.ebean.plugin;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
|
||||
/**
|
||||
* Fired after all beans are parsed. You may implement own parsers to handle custom annotations.
|
||||
* (See test case for example)
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface CustomDeployParser {
|
||||
|
||||
void parse(DeployBeanDescriptorMeta descriptor, DatabasePlatform databasePlatform);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package io.ebean.plugin;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* General deployment information. This is used in {@link CustomDeployParser}.
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*/
|
||||
public interface DeployBeanDescriptorMeta {
|
||||
|
||||
/**
|
||||
* Return a collection of all BeanProperty deployment information.
|
||||
*/
|
||||
public Collection<? extends DeployBeanPropertyMeta> propertiesAll();
|
||||
|
||||
/**
|
||||
* Get a BeanProperty by its name.
|
||||
*/
|
||||
public DeployBeanPropertyMeta getBeanProperty(String secondaryBeanName);
|
||||
|
||||
/**
|
||||
* Return the DeployBeanDescriptorMeta for the given bean class.
|
||||
*/
|
||||
public DeployBeanDescriptorMeta getDeployBeanDescriptorMeta(Class<?> propertyType);
|
||||
|
||||
/**
|
||||
* Returns the discriminator column, if any.
|
||||
* @return
|
||||
*/
|
||||
public String getDiscriminatorColumn();
|
||||
|
||||
public String getBaseTable();
|
||||
|
||||
DeployBeanPropertyMeta idProperty();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.ebean.plugin;
|
||||
|
||||
public interface DeployBeanPropertyAssocMeta extends DeployBeanPropertyMeta {
|
||||
|
||||
/**
|
||||
* Return the mappedBy deployment attribute.
|
||||
* <p>
|
||||
* This is the name of the property in the 'detail' bean that maps back to
|
||||
* this 'master' bean.
|
||||
* </p>
|
||||
*/
|
||||
String getMappedBy();
|
||||
|
||||
/**
|
||||
* Return the base table for this association.
|
||||
* <p>
|
||||
* This has the table name which is used to determine the relationship for
|
||||
* this association.
|
||||
* </p>
|
||||
*/
|
||||
String getBaseTable();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.ebean.plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public interface DeployBeanPropertyMeta {
|
||||
|
||||
/**
|
||||
* Return the name of the property.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* The database column name this is mapped to.
|
||||
*/
|
||||
String getDbColumn();
|
||||
|
||||
/**
|
||||
* Return the bean Field associated with this property.
|
||||
*/
|
||||
Field getField();
|
||||
|
||||
/**
|
||||
* The property is based on a formula.
|
||||
*/
|
||||
void setSqlFormula(String sqlSelect, String sqlJoin);
|
||||
|
||||
/**
|
||||
* Return the bean type.
|
||||
*/
|
||||
Class<?> getOwningType();
|
||||
|
||||
/**
|
||||
* Return the property type.
|
||||
*/
|
||||
Class<?> getPropertyType();
|
||||
|
||||
}
|
||||
@@ -168,6 +168,7 @@ public final class DefaultContainer implements SpiContainer {
|
||||
bootup.addPersistListeners(config.getPersistListeners());
|
||||
bootup.addQueryAdapters(config.getQueryAdapters());
|
||||
bootup.addServerConfigStartup(config.getServerConfigStartupListeners());
|
||||
bootup.addCustomDeployParser(config.getCustomDeployParsers());
|
||||
bootup.addChangeLogInstances(config);
|
||||
bootup.runServerConfigStartup(config);
|
||||
return bootup;
|
||||
|
||||
@@ -11,6 +11,7 @@ import io.ebean.event.changelog.ChangeLogPrepare;
|
||||
import io.ebean.event.changelog.ChangeLogRegister;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.plugin.CustomDeployParser;
|
||||
import io.ebean.util.AnnotationUtil;
|
||||
import io.ebeaninternal.api.CoreLog;
|
||||
import org.slf4j.Logger;
|
||||
@@ -51,6 +52,7 @@ public class BootupClasses implements Predicate<Class<?>> {
|
||||
private final List<Class<? extends BeanPersistListener>> beanPersistListenerCandidates = new ArrayList<>();
|
||||
private final List<Class<? extends BeanQueryAdapter>> beanQueryAdapterCandidates = new ArrayList<>();
|
||||
private final List<Class<? extends ServerConfigStartup>> serverConfigStartupCandidates = new ArrayList<>();
|
||||
private final List<Class<? extends CustomDeployParser>> customDeployParserCandidates = new ArrayList<>();
|
||||
|
||||
private final List<IdGenerator> idGeneratorInstances = new ArrayList<>();
|
||||
private final List<BeanPersistController> beanPersistControllerInstances = new ArrayList<>();
|
||||
@@ -60,6 +62,7 @@ public class BootupClasses implements Predicate<Class<?>> {
|
||||
private final List<BeanPersistListener> beanPersistListenerInstances = new ArrayList<>();
|
||||
private final List<BeanQueryAdapter> beanQueryAdapterInstances = new ArrayList<>();
|
||||
private final List<ServerConfigStartup> serverConfigStartupInstances = new ArrayList<>();
|
||||
private final List<CustomDeployParser> customDeployParserInstances = new ArrayList<>();
|
||||
|
||||
// single objects
|
||||
private Class<? extends ChangeLogPrepare> changeLogPrepareClass;
|
||||
@@ -169,6 +172,10 @@ public class BootupClasses implements Predicate<Class<?>> {
|
||||
add(startupInstances, serverConfigStartupInstances, serverConfigStartupCandidates);
|
||||
}
|
||||
|
||||
public void addCustomDeployParser(List<CustomDeployParser> customDeployParser) {
|
||||
add(customDeployParser, customDeployParserInstances, customDeployParserCandidates);
|
||||
}
|
||||
|
||||
public void addChangeLogInstances(DatabaseConfig config) {
|
||||
readAuditPrepare = config.getReadAuditPrepare();
|
||||
readAuditLogger = config.getReadAuditLogger();
|
||||
@@ -285,6 +292,10 @@ public class BootupClasses implements Predicate<Class<?>> {
|
||||
return createAdd(beanQueryAdapterInstances, beanQueryAdapterCandidates);
|
||||
}
|
||||
|
||||
public List<CustomDeployParser> getCustomDeployParsers() {
|
||||
return createAdd(customDeployParserInstances, customDeployParserCandidates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of Embeddable classes.
|
||||
*/
|
||||
@@ -404,6 +415,11 @@ public class BootupClasses implements Predicate<Class<?>> {
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (CustomDeployParser.class.isAssignableFrom(cls)) {
|
||||
customDeployParserCandidates.add((Class<? extends CustomDeployParser>) cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
// single instances, last assigned wins
|
||||
if (ChangeLogListener.class.isAssignableFrom(cls)) {
|
||||
changeLogListenerClass = (Class<? extends ChangeLogListener>) cls;
|
||||
|
||||
@@ -74,6 +74,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
private final BeanFinderManager beanFinderManager;
|
||||
private final PersistListenerManager persistListenerManager;
|
||||
private final BeanQueryAdapterManager beanQueryAdapterManager;
|
||||
private final CustomDeployParserManager customDeployParserManager;
|
||||
private final NamingConvention namingConvention;
|
||||
private final DeployCreateProperties createProperties;
|
||||
private final BeanManagerFactory beanManagerFactory;
|
||||
@@ -154,6 +155,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
this.persistListenerManager = new PersistListenerManager(bootupClasses);
|
||||
this.beanQueryAdapterManager = new BeanQueryAdapterManager(bootupClasses);
|
||||
this.beanFinderManager = new BeanFinderManager(bootupClasses);
|
||||
this.customDeployParserManager = new CustomDeployParserManager(bootupClasses);
|
||||
this.transientProperties = new TransientProperties();
|
||||
this.changeLogPrepare = config.changeLogPrepare(bootupClasses.getChangeLogPrepare());
|
||||
this.changeLogListener = config.changeLogListener(bootupClasses.getChangeLogListener());
|
||||
@@ -301,6 +303,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
readEntityBeanTable();
|
||||
readEntityDeploymentAssociations();
|
||||
readInheritedIdGenerators();
|
||||
deployInfoMap.values().forEach(customDeployParserManager::parse);
|
||||
// creates the BeanDescriptors
|
||||
readEntityRelationships();
|
||||
List<BeanDescriptor<?>> list = new ArrayList<>(descMap.values());
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.ebean.plugin.CustomDeployParser;
|
||||
import io.ebeaninternal.server.core.bootup.BootupClasses;
|
||||
import io.ebeaninternal.server.deploy.parse.DeployBeanInfo;
|
||||
|
||||
public class CustomDeployParserManager {
|
||||
|
||||
private final List<CustomDeployParser> parsers;
|
||||
|
||||
public CustomDeployParserManager(BootupClasses bootupClasses) {
|
||||
parsers = bootupClasses.getCustomDeployParsers();
|
||||
}
|
||||
|
||||
public void parse(DeployBeanInfo<?> value) {
|
||||
for (CustomDeployParser parser : parsers) {
|
||||
parser.parse(value.getDescriptor(), value.getUtil().getDbPlatform());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+17
-2
@@ -16,6 +16,7 @@ import io.ebean.event.BeanPostConstructListener;
|
||||
import io.ebean.event.BeanPostLoad;
|
||||
import io.ebean.event.BeanQueryAdapter;
|
||||
import io.ebean.event.changelog.ChangeLogFilter;
|
||||
import io.ebean.plugin.DeployBeanDescriptorMeta;
|
||||
import io.ebean.text.PathProperties;
|
||||
import io.ebean.util.AnnotationUtil;
|
||||
import io.ebean.util.SplitName;
|
||||
@@ -55,7 +56,7 @@ import java.util.Set;
|
||||
/**
|
||||
* Describes Beans including their deployment information.
|
||||
*/
|
||||
public class DeployBeanDescriptor<T> {
|
||||
public class DeployBeanDescriptor<T> implements DeployBeanDescriptorMeta {
|
||||
|
||||
private static final Map<String, String> EMPTY_NAMED_QUERY = new HashMap<>();
|
||||
|
||||
@@ -199,7 +200,7 @@ public class DeployBeanDescriptor<T> {
|
||||
/**
|
||||
* Return the DeployBeanInfo for the given bean class.
|
||||
*/
|
||||
DeployBeanInfo<?> getDeploy(Class<?> cls) {
|
||||
public DeployBeanInfo<?> getDeploy(Class<?> cls) {
|
||||
return manager.deploy(cls);
|
||||
}
|
||||
|
||||
@@ -619,6 +620,7 @@ public class DeployBeanDescriptor<T> {
|
||||
* Return the base table. Only properties mapped to the base table are by
|
||||
* default persisted.
|
||||
*/
|
||||
@Override
|
||||
public String getBaseTable() {
|
||||
return baseTable;
|
||||
}
|
||||
@@ -696,6 +698,7 @@ public class DeployBeanDescriptor<T> {
|
||||
/**
|
||||
* Get a BeanProperty by its name.
|
||||
*/
|
||||
@Override
|
||||
public DeployBeanProperty getBeanProperty(String propName) {
|
||||
return propMap.get(propName);
|
||||
}
|
||||
@@ -815,6 +818,7 @@ public class DeployBeanDescriptor<T> {
|
||||
/**
|
||||
* Return a collection of all BeanProperty deployment information.
|
||||
*/
|
||||
@Override
|
||||
public Collection<DeployBeanProperty> propertiesAll() {
|
||||
return propMap.values();
|
||||
}
|
||||
@@ -884,6 +888,7 @@ public class DeployBeanDescriptor<T> {
|
||||
/**
|
||||
* Return the BeanProperty that is the Id.
|
||||
*/
|
||||
@Override
|
||||
public DeployBeanProperty idProperty() {
|
||||
if (idProperty != null) {
|
||||
return idProperty;
|
||||
@@ -1180,4 +1185,14 @@ public class DeployBeanDescriptor<T> {
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDiscriminatorColumn() {
|
||||
return inheritInfo == null ? null : inheritInfo.getDiscriminatorColumn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeployBeanDescriptorMeta getDeployBeanDescriptorMeta(Class<?> propertyType) {
|
||||
return getDeploy(propertyType).getDescriptor();
|
||||
}
|
||||
}
|
||||
|
||||
+22
-2
@@ -1,11 +1,25 @@
|
||||
package io.ebeaninternal.server.deploy.meta;
|
||||
|
||||
import io.ebean.annotation.*;
|
||||
import io.ebean.annotation.CreatedTimestamp;
|
||||
import io.ebean.annotation.DocCode;
|
||||
import io.ebean.annotation.DocProperty;
|
||||
import io.ebean.annotation.DocSortable;
|
||||
import io.ebean.annotation.Formula;
|
||||
import io.ebean.annotation.MutationDetection;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.annotation.SoftDelete;
|
||||
import io.ebean.annotation.UpdatedTimestamp;
|
||||
import io.ebean.annotation.WhenCreated;
|
||||
import io.ebean.annotation.WhenModified;
|
||||
import io.ebean.annotation.Where;
|
||||
import io.ebean.annotation.WhoCreated;
|
||||
import io.ebean.annotation.WhoModified;
|
||||
import io.ebean.config.ScalarTypeConverter;
|
||||
import io.ebean.config.dbplatform.DbDefaultValue;
|
||||
import io.ebean.config.dbplatform.DbEncrypt;
|
||||
import io.ebean.config.dbplatform.DbEncryptFunction;
|
||||
import io.ebean.core.type.ScalarType;
|
||||
import io.ebean.plugin.DeployBeanPropertyMeta;
|
||||
import io.ebean.util.AnnotationUtil;
|
||||
import io.ebeaninternal.server.core.InternString;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
@@ -35,7 +49,7 @@ import java.util.Set;
|
||||
* Description of a property of a bean. Includes its deployment information such
|
||||
* as database column mapping information.
|
||||
*/
|
||||
public class DeployBeanProperty {
|
||||
public class DeployBeanProperty implements DeployBeanPropertyMeta {
|
||||
|
||||
private static final int ID_ORDER = 1000000;
|
||||
private static final int UNIDIRECTIONAL_ORDER = 100000;
|
||||
@@ -406,6 +420,7 @@ public class DeployBeanProperty {
|
||||
this.owningType = owningType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getOwningType() {
|
||||
return owningType;
|
||||
}
|
||||
@@ -434,6 +449,7 @@ public class DeployBeanProperty {
|
||||
/**
|
||||
* Return the name of the property.
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -448,6 +464,7 @@ public class DeployBeanProperty {
|
||||
/**
|
||||
* Return the bean Field associated with this property.
|
||||
*/
|
||||
@Override
|
||||
public Field getField() {
|
||||
return field;
|
||||
}
|
||||
@@ -551,6 +568,7 @@ public class DeployBeanProperty {
|
||||
/**
|
||||
* The property is based on a formula.
|
||||
*/
|
||||
@Override
|
||||
public void setSqlFormula(String formulaSelect, String formulaJoin) {
|
||||
this.sqlFormulaSelect = formulaSelect;
|
||||
this.sqlFormulaJoin = formulaJoin.isEmpty() ? null : formulaJoin;
|
||||
@@ -654,6 +672,7 @@ public class DeployBeanProperty {
|
||||
/**
|
||||
* The database column name this is mapped to.
|
||||
*/
|
||||
@Override
|
||||
public String getDbColumn() {
|
||||
if (sqlFormulaSelect != null) {
|
||||
return sqlFormulaSelect;
|
||||
@@ -847,6 +866,7 @@ public class DeployBeanProperty {
|
||||
/**
|
||||
* Return the property type.
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getPropertyType() {
|
||||
return propertyType;
|
||||
}
|
||||
|
||||
+8
-1
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.deploy.meta;
|
||||
|
||||
import io.ebean.plugin.DeployBeanPropertyAssocMeta;
|
||||
import io.ebeaninternal.server.deploy.BeanCascadeInfo;
|
||||
import io.ebeaninternal.server.deploy.BeanTable;
|
||||
import io.ebeaninternal.server.deploy.PropertyForeignKey;
|
||||
@@ -7,7 +8,7 @@ import io.ebeaninternal.server.deploy.PropertyForeignKey;
|
||||
/**
|
||||
* Abstract base for properties mapped to an associated bean, list, set or map.
|
||||
*/
|
||||
public abstract class DeployBeanPropertyAssoc<T> extends DeployBeanProperty {
|
||||
public abstract class DeployBeanPropertyAssoc<T> extends DeployBeanProperty implements DeployBeanPropertyAssocMeta {
|
||||
|
||||
/**
|
||||
* The type of the joined bean.
|
||||
@@ -129,6 +130,7 @@ public abstract class DeployBeanPropertyAssoc<T> extends DeployBeanProperty {
|
||||
* this 'master' bean.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public String getMappedBy() {
|
||||
return mappedBy;
|
||||
}
|
||||
@@ -173,4 +175,9 @@ public abstract class DeployBeanPropertyAssoc<T> extends DeployBeanProperty {
|
||||
public void setTargetType(Class<?> targetType) {
|
||||
this.targetType = (Class<T>)targetType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseTable() {
|
||||
return getBeanTable().getBaseTable();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user