diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java index c6f238484..b1f255066 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java @@ -60,12 +60,12 @@ public class BeanDescriptor implements MetaBeanInfo { private final ConcurrentHashMap queryPlanCache = new ConcurrentHashMap(); - private final ConcurrentHashMap elGetCache = new ConcurrentHashMap(); + private final ConcurrentHashMap elCache = new ConcurrentHashMap(); + + private final ConcurrentHashMap elDeployCache = new ConcurrentHashMap(); private final ConcurrentHashMap> comparatorCache = new ConcurrentHashMap>(); - private final ConcurrentHashMap fkeyMap = new ConcurrentHashMap(); - public enum EntityType { ORM, EMBEDDED, SQL } @@ -630,7 +630,7 @@ public class BeanDescriptor implements MetaBeanInfo { * foreign keys don't require an extra join. */ public void add(BeanFkeyProperty fkey) { - fkeyMap.put(fkey.getName(), fkey); + elDeployCache.put(fkey.getName(), fkey); } public void initialiseFkeys() { @@ -1379,7 +1379,15 @@ public class BeanDescriptor implements MetaBeanInfo { * Get an Expression language Value object. */ public ElPropertyValue getElGetValue(String propName) { - return getElPropertyValue(propName, false); + ElPropertyValue elGetValue = elCache.get(propName); + if (elGetValue != null) { + return elGetValue; + } + elGetValue = buildElGetValue(propName, null, false); + if (elGetValue != null) { + elCache.put(propName, elGetValue); + } + return elGetValue; } /** @@ -1389,36 +1397,30 @@ public class BeanDescriptor implements MetaBeanInfo { *

*/ public ElPropertyDeploy getElPropertyDeploy(String propName) { - ElPropertyDeploy fk = fkeyMap.get(propName); - if (fk != null) { - return fk; + ElPropertyDeploy elProp = elDeployCache.get(propName); + if (elProp != null) { + return elProp; } - return getElPropertyValue(propName, true); - } - - private ElPropertyValue getElPropertyValue(String propName, boolean propertyDeploy) { - ElPropertyValue elGetValue = elGetCache.get(propName); - if (elGetValue == null) { - // need to build it potentially navigating the BeanDescriptors - elGetValue = buildElGetValue(propName, null, propertyDeploy); - if (elGetValue == null) { - return null; - } - if (elGetValue instanceof BeanFkeyProperty) { - fkeyMap.put(propName, (BeanFkeyProperty) elGetValue); - } else { - elGetCache.put(propName, elGetValue); - } + if (!propName.contains(".")) { + // No period means simple property and no need to look for + // foreign key properties (in order to avoid an extra join) + elProp = getElGetValue(propName); + } else { + elProp = buildElGetValue(propName, null, true); } - return elGetValue; + if (elProp != null) { + elDeployCache.put(propName, elProp); + } + return elProp; } protected ElPropertyValue buildElGetValue(String propName, ElPropertyChainBuilder chain, boolean propertyDeploy) { if (propertyDeploy && chain != null) { - BeanFkeyProperty fk = fkeyMap.get(propName); - if (fk != null) { - return fk.create(chain.getExpression(), chain.isContainsMany()); + ElPropertyDeploy fk = elDeployCache.get(propName); + if (fk != null && fk instanceof BeanFkeyProperty) { + // propertyDeploy chain for foreign key column + return ((BeanFkeyProperty)fk).create(chain.getExpression(), chain.isContainsMany()); } } diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanFkeyProperty.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanFkeyProperty.java index 4f5ae3069..cf9f6873f 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanFkeyProperty.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanFkeyProperty.java @@ -31,6 +31,10 @@ public final class BeanFkeyProperty implements ElPropertyValue { this.placeHolder = calcPlaceHolder(prefix, dbColumn); } + public String toString() { + return "prefix:"+prefix+" name:"+name+" dbColumn:"+dbColumn+" ph:"+placeHolder; + } + public int getDeployOrder() { return deployOrder; } diff --git a/src/main/java/com/avaje/ebeaninternal/server/el/ElPropertyChain.java b/src/main/java/com/avaje/ebeaninternal/server/el/ElPropertyChain.java index af9db6390..1c5526389 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/el/ElPropertyChain.java +++ b/src/main/java/com/avaje/ebeaninternal/server/el/ElPropertyChain.java @@ -8,6 +8,8 @@ import com.avaje.ebeaninternal.server.lib.util.StringHelper; import com.avaje.ebeaninternal.server.query.SplitName; import com.avaje.ebeaninternal.server.type.ScalarType; +import java.util.Arrays; + /** * A ElGetValue based on a chain of properties. @@ -41,9 +43,9 @@ public class ElPropertyChain implements ElPropertyValue { private final ScalarType scalarType; private final ElPropertyValue lastElPropertyValue; - + public ElPropertyChain(boolean containsMany, boolean embedded, String expression, ElPropertyValue[] chain) { - + this.containsMany = containsMany; this.chain = chain; this.expression = expression; @@ -51,19 +53,19 @@ public class ElPropertyChain implements ElPropertyValue { if (dotPos > -1){ this.name = expression.substring(dotPos+1); if (embedded){ - int embPos = expression.lastIndexOf('.',dotPos-1); + int embPos = expression.lastIndexOf('.',dotPos-1); this.prefix = embPos == -1 ? null : expression.substring(0, embPos); - + } else { this.prefix = expression.substring(0, dotPos); } } else { this.prefix = null; this.name = expression; - } + } this.assocId = chain[chain.length-1].isAssocId(); - + this.last = chain.length-1; this.lastBeanProperty = chain[chain.length-1].getBeanProperty(); if (lastBeanProperty != null){ @@ -77,6 +79,10 @@ public class ElPropertyChain implements ElPropertyValue { this.placeHolderEncrypted = getElPlaceHolder(prefix, lastElPropertyValue, true); } + public String toString() { + return "expr:"+expression+" chain:"+ Arrays.toString(chain); + } + private String getElPlaceHolder(String prefix, ElPropertyValue lastElPropertyValue, boolean encrypted) { if (prefix == null){ return lastElPropertyValue.getElPlaceholder(encrypted);