#322 - RawSql fetch object with inheritance

This commit is contained in:
Robin Bygrave
2015-07-14 23:09:38 +12:00
parent 0f7c9da5d2
commit e95d3304bf
21 changed files with 432 additions and 75 deletions
@@ -533,7 +533,7 @@ public class BeanProperty implements ElPropertyValue {
sqlBeanLoad.load(this);
}
public void buildSelectExpressionChain(String prefix, List<String> selectChain) {
public void buildRawSqlSelectChain(String prefix, List<String> selectChain) {
if (prefix == null) {
selectChain.add(name);
} else {
@@ -225,7 +225,8 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
return createElPropertyValue(propName, remainder, chain, propertyDeploy);
}
public void buildSelectExpressionChain(String prefix, List<String> selectChain) {
@Override
public void buildRawSqlSelectChain(String prefix, List<String> selectChain) {
// do not add to the selectChain at the top level of the Many bean
}
@@ -1,13 +1,5 @@
package com.avaje.ebeaninternal.server.deploy;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.persistence.PersistenceException;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.Query;
import com.avaje.ebean.SqlUpdate;
@@ -28,6 +20,13 @@ import com.avaje.ebeaninternal.server.query.SqlJoinType;
import com.avaje.ebeaninternal.server.text.json.ReadJson;
import com.avaje.ebeaninternal.server.text.json.WriteJson;
import javax.persistence.PersistenceException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Property mapped to a joined bean.
*/
@@ -273,17 +272,27 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
return embeddedProps;
}
public void buildSelectExpressionChain(String prefix, List<String> selectChain) {
@Override
public void buildRawSqlSelectChain(String prefix, List<String> selectChain) {
prefix = SplitName.add(prefix, name);
if (!embedded){
targetIdBinder.buildSelectExpressionChain(prefix, selectChain);
InheritInfo inheritInfo = targetDescriptor.getInheritInfo();
if (inheritInfo != null) {
// expect the discriminator column to be included in order
// to determine the inheritance type so we add it to the
// selectChain (so that it takes a position in the resultSet)
String discriminatorColumn = inheritInfo.getDiscriminatorColumn();
String discProperty = prefix + "." + discriminatorColumn;
selectChain.add(discProperty);
}
targetIdBinder.buildRawSqlSelectChain(prefix, selectChain);
} else {
for (int i = 0; i < embeddedProps.length; i++) {
embeddedProps[i].buildSelectExpressionChain(prefix, selectChain);
}
embeddedProps[i].buildRawSqlSelectChain(prefix, selectChain);
}
}
}
@@ -1,13 +1,6 @@
package com.avaje.ebeaninternal.server.deploy.id;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
@@ -15,6 +8,12 @@ import com.avaje.ebeaninternal.server.deploy.DbReadContext;
import com.avaje.ebeaninternal.server.deploy.DbSqlContext;
import com.avaje.ebeaninternal.server.type.DataBind;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
/**
* Binds id values to prepared statements.
*/
@@ -135,7 +134,7 @@ public interface IdBinder {
*/
public String getIdInValueExprDelete(int size);
public void buildSelectExpressionChain(String prefix, List<String> selectChain);
public void buildRawSqlSelectChain(String prefix, List<String> selectChain);
/**
* Read the id value from the result set and set it to the bean also returning
@@ -1,11 +1,5 @@
package com.avaje.ebeaninternal.server.deploy.id;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
@@ -17,6 +11,12 @@ import com.avaje.ebeaninternal.server.deploy.DbSqlContext;
import com.avaje.ebeaninternal.server.query.SplitName;
import com.avaje.ebeaninternal.server.type.DataBind;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
/**
* Bind an Id that is an Embedded bean.
*/
@@ -115,12 +115,12 @@ public final class IdBinderEmbedded implements IdBinder {
return embIdProperty.getName();
}
public void buildSelectExpressionChain(String prefix, List<String> selectChain) {
public void buildRawSqlSelectChain(String prefix, List<String> selectChain) {
prefix = SplitName.add(prefix, embIdProperty.getName());
for (int i = 0; i < props.length; i++) {
props[i].buildSelectExpressionChain(prefix, selectChain);
props[i].buildRawSqlSelectChain(prefix, selectChain);
}
}
@@ -1,13 +1,6 @@
package com.avaje.ebeaninternal.server.deploy.id;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
@@ -15,6 +8,12 @@ import com.avaje.ebeaninternal.server.deploy.DbReadContext;
import com.avaje.ebeaninternal.server.deploy.DbSqlContext;
import com.avaje.ebeaninternal.server.type.DataBind;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
/**
* For beans with no id properties AKA report type beans.
*/
@@ -38,7 +37,7 @@ public final class IdBinderEmpty implements IdBinder {
return pathPrefix;
}
public void buildSelectExpressionChain(String prefix, List<String> selectChain) {
public void buildRawSqlSelectChain(String prefix, List<String> selectChain) {
}
public int getPropertyCount() {
@@ -1,13 +1,6 @@
package com.avaje.ebeaninternal.server.deploy.id;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
import com.avaje.ebeaninternal.server.core.InternString;
@@ -17,6 +10,12 @@ import com.avaje.ebeaninternal.server.deploy.DbSqlContext;
import com.avaje.ebeaninternal.server.type.DataBind;
import com.avaje.ebeaninternal.server.type.ScalarType;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
/**
* Bind an Id where the Id is made of a single property (not embedded).
*/
@@ -59,9 +58,9 @@ public final class IdBinderSimple implements IdBinder {
return sb.toString();
}
public void buildSelectExpressionChain(String prefix, List<String> selectChain) {
public void buildRawSqlSelectChain(String prefix, List<String> selectChain) {
idProperty.buildSelectExpressionChain(prefix, selectChain);
idProperty.buildRawSqlSelectChain(prefix, selectChain);
}
/**
@@ -31,9 +31,11 @@ public class CQueryPlanRawSql extends CQueryPlan {
private int[] createIndexPositions(OrmQueryRequest<?> request, SqlTree sqlTree) {
List<String> chain = sqlTree.buildSelectExpressionChain();
List<String> chain = sqlTree.buildRawSqlSelectChain();
ColumnMapping columnMapping = request.getQuery().getRawSql().getColumnMapping();
// if the top level bean has inheritance expect first column
// to be the discriminator type column (and use offset 1)
InheritInfo inheritInfo = request.getBeanDescriptor().getInheritInfo();
boolean addDiscriminator = inheritInfo != null;
int offset = addDiscriminator ? 1 : 0;
@@ -43,12 +45,25 @@ public class CQueryPlanRawSql extends CQueryPlan {
// discriminator column must always be first in the query
indexPositions[0] = 1;
}
// set the resultSet index positions for the property expressions
for (int i = 0; i < chain.size(); i++) {
String expr = chain.get(i);
int indexPos = 1 + columnMapping.getIndexPosition(expr);
indexPositions[i + offset] = indexPos;
}
// check and handle the case where a discriminator column for
// an associated bean is in the raw SQL but is mapped columnIgnore
for (int i = 0; i <indexPositions.length ; i++) {
if (indexPositions[i] == 0) {
if (i < indexPositions.length) {
// expect discriminator column to immediately proceed id column
indexPositions[i] = indexPositions[i+1] - 1;
}
}
}
return indexPositions;
}
}
@@ -1,13 +1,13 @@
package com.avaje.ebeaninternal.server.query;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* Represents the SELECT clause part of the SQL query.
*/
@@ -83,9 +83,9 @@ public class SqlTree {
/**
* Build a select expression chain for RawSql.
*/
public List<String> buildSelectExpressionChain() {
public List<String> buildRawSqlSelectChain() {
ArrayList<String> list = new ArrayList<String>();
rootNode.buildSelectExpressionChain(list);
rootNode.buildRawSqlSelectChain(list);
return list;
}
@@ -1,17 +1,20 @@
package com.avaje.ebeaninternal.server.query;
import java.sql.SQLException;
import java.util.List;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.server.deploy.DbReadContext;
import com.avaje.ebeaninternal.server.deploy.DbSqlContext;
import java.sql.SQLException;
import java.util.List;
public interface SqlTreeNode {
String COMMA = ", ";
void buildSelectExpressionChain(List<String> selectChain);
/**
* Build the select chain for a RawSql query.
*/
void buildRawSqlSelectChain(List<String> selectChain);
/**
* Append the required column information to the SELECT part of the sql
@@ -137,18 +137,18 @@ public class SqlTreeNodeBean implements SqlTreeNode {
}
}
public void buildSelectExpressionChain(List<String> selectChain) {
public void buildRawSqlSelectChain(List<String> selectChain) {
if (readId) {
idBinder.buildSelectExpressionChain(prefix, selectChain);
idBinder.buildRawSqlSelectChain(prefix, selectChain);
}
for (int i = 0, x = properties.length; i < x; i++) {
properties[i].buildSelectExpressionChain(prefix, selectChain);
properties[i].buildRawSqlSelectChain(prefix, selectChain);
}
// recursively continue reading...
for (int i = 0; i < children.length; i++) {
// read each child... and let them set their
// values back to this localBean
children[i].buildSelectExpressionChain(selectChain);
children[i].buildRawSqlSelectChain(selectChain);
}
}
@@ -1,9 +1,5 @@
package com.avaje.ebeaninternal.server.query;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssoc;
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
@@ -11,6 +7,10 @@ import com.avaje.ebeaninternal.server.deploy.DbReadContext;
import com.avaje.ebeaninternal.server.deploy.DbSqlContext;
import com.avaje.ebeaninternal.server.deploy.TableJoin;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* The purpose is to add an extra join to the query.
* <p>
@@ -35,7 +35,8 @@ public class SqlTreeNodeExtraJoin implements SqlTreeNode {
this.manyJoin = assocBeanProperty instanceof BeanPropertyAssocMany<?>;
}
public void buildSelectExpressionChain(List<String> selectChain) {
@Override
public void buildRawSqlSelectChain(List<String> selectChain) {
// nothing to add
}
@@ -49,7 +50,6 @@ public class SqlTreeNodeExtraJoin implements SqlTreeNode {
return manyJoin;
}
public String getName() {
return prefix;
}
@@ -1,9 +1,5 @@
package com.avaje.ebeaninternal.server.query;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssoc;
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
@@ -12,6 +8,9 @@ import com.avaje.ebeaninternal.server.deploy.DbReadContext;
import com.avaje.ebeaninternal.server.deploy.DbSqlContext;
import com.avaje.ebeaninternal.server.deploy.TableJoin;
import java.sql.SQLException;
import java.util.List;
/**
* Join to Many (or child of a many) to support where clause predicates on many properties.
*/
@@ -76,7 +75,7 @@ public class SqlTreeNodeManyWhereJoin implements SqlTreeNode {
}
}
public void buildSelectExpressionChain(List<String> selectChain) {
public void buildRawSqlSelectChain(List<String> selectChain) {
// nothing to add
}