cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject svn commit: r628929 - in /cayenne/main/trunk: framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/ framework/cayenne-jdk1.5-unpublished/src/main...
Date Tue, 19 Feb 2008 00:02:55 GMT
Author: aadamchik
Date: Mon Feb 18 16:02:53 2008
New Revision: 628929

URL: http://svn.apache.org/viewvc?rev=628929&view=rev
Log:
CAY-839 Support combination of Persistent objects and scalars in query results
(backend implementation)

Added:
    cayenne/main/trunk/itests/jpa-chapter3/src/test/java/org/apache/cayenne/jpa/itest/ch3/_3_6_1_QueryAPITest.java
    cayenne/main/trunk/itests/jpa-chapter3/src/test/java/org/apache/cayenne/jpa/itest/ch3/_3_6_6_SQLQueriesTest.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/EntityResult.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/FieldResult.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/SQLResultSetMapping.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLArrayResultTest.java
    cayenne/main/trunk/itests/jpa-chapter3/src/main/java/org/apache/cayenne/jpa/itest/ch3/entity/SimpleEntity.java
    cayenne/main/trunk/itests/jpa-chapter4/src/test/java/org/apache/cayenne/jpa/itest/ch4/_4_2_1_SelectStatementTest.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java?rev=628929&r1=628928&r2=628929&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java Mon Feb 18 16:02:53 2008
@@ -41,7 +41,6 @@
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.ObjRelationship;
 import org.apache.cayenne.query.EntityResult;
-import org.apache.cayenne.query.FieldResult;
 import org.apache.cayenne.query.ObjectIdQuery;
 import org.apache.cayenne.query.PrefetchSelectQuery;
 import org.apache.cayenne.query.PrefetchTreeNode;
@@ -432,16 +431,28 @@
                 if (rsMapping == null) {
                     converter = new SingleObjectConversionStrategy();
                 }
-                else if (rsMapping.getEntityResults().size() == 1
-                        && rsMapping.getColumnResults().size() == 0) {
-                    converter = new SingleObjectConversionStrategy();
-                }
-                else if (rsMapping.getEntityResults().size() == 0
-                        && rsMapping.getColumnResults().size() == 1) {
-                    converter = new SingleScalarConversionStrategy();
-                }
                 else {
-                    converter = new MixedConversionStrategy();
+
+                    int entityResultCount = 0;
+                    int columnResultCount = 0;
+                    for (Object result : rsMapping.getResultDescriptors()) {
+                        if (result instanceof String) {
+                            columnResultCount++;
+                        }
+                        else {
+                            entityResultCount++;
+                        }
+                    }
+
+                    if (entityResultCount == 1 && columnResultCount == 0) {
+                        converter = new SingleObjectConversionStrategy();
+                    }
+                    else if (entityResultCount == 0 && columnResultCount == 1) {
+                        converter = new SingleScalarConversionStrategy();
+                    }
+                    else {
+                        converter = new MixedConversionStrategy();
+                    }
                 }
 
                 converter.convert(mainRows);
@@ -571,15 +582,15 @@
                 List<DataRow> dataRows) {
             List<DataRow> normalized = new ArrayList<DataRow>(dataRows.size());
 
-            FieldResult[] fields = entityMapping.getDbFields(domain.getEntityResolver());
-            int rowCapacity = (int) Math.ceil(fields.length / 0.75);
+            Map<String, String> fields = entityMapping.getDbFields(domain
+                    .getEntityResolver());
+            int rowCapacity = (int) Math.ceil(fields.size() / 0.75);
 
             for (DataRow src : dataRows) {
                 DataRow target = new DataRow(rowCapacity);
 
-                for (FieldResult columnMapping : fields) {
-                    target.put(columnMapping.getAttributeName(), src.get(columnMapping
-                            .getColumn()));
+                for (Map.Entry<String, String> field : fields.entrySet()) {
+                    target.put(field.getKey(), src.get(field.getValue()));
                 }
 
                 normalized.add(target);
@@ -606,18 +617,23 @@
         @Override
         void convert(List<DataRow> mainRows) {
 
+            List<DataRow> normalized;
+            
             // convert data rows to standardized format...
             SQLResultSetMapping rsMapping = metadata.getResultSetMapping();
             if (rsMapping != null) {
                 // expect 1 and only 1 entityMapping...
-                EntityResult entityMapping = rsMapping.getEntityResults().get(0);
-                mainRows = toNormalizedDataRows(entityMapping, mainRows);
+                EntityResult entityMapping = rsMapping.getEntityResult(0);
+                normalized = toNormalizedDataRows(entityMapping, mainRows);
+            }
+            else {
+                normalized = mainRows;
             }
 
             ClassDescriptor descriptor = metadata.getClassDescriptor();
             PrefetchTreeNode prefetchTree = metadata.getPrefetchTree();
 
-            List<Persistent> objects = toObjects(descriptor, prefetchTree, mainRows);
+            List<Persistent> objects = toObjects(descriptor, prefetchTree, normalized);
             updateResponse(mainRows, objects);
 
             // apply POST_LOAD callback
@@ -638,12 +654,10 @@
 
             SQLResultSetMapping rsMapping = metadata.getResultSetMapping();
 
-            List<String> columns = rsMapping.getColumnResults();
-
             int rowsLen = mainRows.size();
 
             List objects = new ArrayList(rowsLen);
-            String column = columns.get(0);
+            String column = rsMapping.getColumnResult(0);
 
             // add scalars to the result
             for (DataRow row : mainRows) {
@@ -664,33 +678,33 @@
 
             SQLResultSetMapping rsMapping = metadata.getResultSetMapping();
 
-            List<EntityResult> entities = rsMapping.getEntityResults();
-            List<String> columns = rsMapping.getColumnResults();
-
-            // pass 1 - init Object[]'s and resolve scalars
+            // pass 1 - init Object[]'s and resolve scalars for each row
 
-            int resultWidth = entities.size() + columns.size();
-            int scalarOffset = entities.size();
+            int resultWidth = rsMapping.getResultDescriptors().size();
+            int[] entityPositions = rsMapping.getEntityResultPositions();
+            int[] columnPositions = rsMapping.getColumnResultPositions();
 
             for (DataRow row : mainRows) {
                 Object[] resultRow = new Object[resultWidth];
-                for (int i = 0; i < columns.size(); i++) {
-                    resultRow[scalarOffset + i] = row.get(columns.get(i));
+                for (int i = 0; i < columnPositions.length; i++) {
+                    int pos = columnPositions[i];
+                    resultRow[pos] = row.get(rsMapping.getColumnResult(pos));
                 }
                 objects.add(resultRow);
             }
 
-            // pass 2 - resolve individual object lists
-            List[] resultLists = new List[scalarOffset];
-            for (int i = 0; i < scalarOffset; i++) {
-                EntityResult entityMapping = entities.get(i);
+            // pass 2 - resolve individual object columns, and then update the rows...
+            List[] resultLists = new List[entityPositions.length];
+            for (int i = 0; i < entityPositions.length; i++) {
+                int pos = entityPositions[i];
+                EntityResult entityMapping = rsMapping.getEntityResult(pos);
                 List<DataRow> normalized = toNormalizedDataRows(entityMapping, mainRows);
 
                 List<Persistent> nextResult = toObjects(entityMapping
                         .getClassDescriptor(domain.getEntityResolver()), null, normalized);
 
                 for (int j = 0; j < rowsLen; j++) {
-                    objects.get(j)[i] = nextResult.get(j);
+                    objects.get(j)[pos] = nextResult.get(j);
                 }
 
                 resultLists[i] = nextResult;
@@ -704,7 +718,7 @@
                     .getCallbackRegistry();
 
             if (!callbackRegistry.isEmpty(LifecycleEvent.POST_LOAD)) {
-                for (int i = 0; i < scalarOffset; i++) {
+                for (int i = 0; i < entityPositions.length; i++) {
                     callbackRegistry.performCallbacks(
                             LifecycleEvent.POST_LOAD,
                             resultLists[i]);

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java?rev=628929&r1=628928&r2=628929&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java Mon Feb 18 16:02:53 2008
@@ -20,6 +20,7 @@
 
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.cayenne.CayenneRuntimeException;
@@ -55,9 +56,21 @@
     @Override
     public boolean visitIdentifier(EJBQLExpression expression) {
 
+        Map<String, String> xfields = null;
+        if (context.isAppendingResultColumns()) {
+            xfields = context.nextEntityResult().getDbFields(context.getEntityResolver());
+        }
+
+        // assign whatever we have to a final ivar so that it can be accessed within
+        // the inner class
+        final Map<String, String> fields = xfields;
         final String idVar = expression.getText();
 
-        // append all table columns
+        // append all table columns ... the trick is to follow the algorithm for
+        // describing the fields in the expression compiler, so that we could assign
+        // columns labels from FieldResults in the order we encounter them here...
+        // TODO: andrus 2008/02/17 - this is a bit of a hack, think of a better solution
+
         ClassDescriptor descriptor = context.getEntityDescriptor(idVar);
 
         PropertyVisitor visitor = new PropertyVisitor() {
@@ -77,7 +90,6 @@
                         throw new CayenneRuntimeException(
                                 "ObjAttribute has no component: " + oa.getName());
                     }
-
                     else if (pathPart instanceof DbRelationship) {
 
                         if (marker == null) {
@@ -94,7 +106,8 @@
                         lhsId = rhsId;
                     }
                     else if (pathPart instanceof DbAttribute) {
-                        appendColumn(idVar, oa, (DbAttribute) pathPart, oa.getType());
+                        appendColumn(idVar, oa, (DbAttribute) pathPart, fields, oa
+                                .getType());
                     }
                 }
                 return true;
@@ -116,7 +129,7 @@
 
                 for (DbJoin join : dbRel.getJoins()) {
                     DbAttribute src = join.getSource();
-                    appendColumn(idVar, null, src);
+                    appendColumn(idVar, null, src, fields);
                 }
             }
         };
@@ -128,13 +141,13 @@
         // append id columns ... (some may have been appended already via relationships)
         DbEntity table = descriptor.getEntity().getDbEntity();
         for (DbAttribute pk : table.getPrimaryKeys()) {
-            appendColumn(idVar, null, pk);
+            appendColumn(idVar, null, pk, fields);
         }
 
         // append inheritance discriminator columns...
         Iterator<DbAttribute> discriminatorColumns = descriptor.getDiscriminatorColumns();
         while (discriminatorColumns.hasNext()) {
-            appendColumn(idVar, null, discriminatorColumns.next());
+            appendColumn(idVar, null, discriminatorColumns.next(), fields);
         }
 
         return false;
@@ -142,22 +155,22 @@
 
     private void appendColumn(
             String identifier,
-            ObjAttribute objectAttribute,
-            DbAttribute column) {
-        appendColumn(identifier, objectAttribute, column, null);
+            ObjAttribute property,
+            DbAttribute column,
+            Map<String, String> fields) {
+        appendColumn(identifier, property, column, fields, null);
     }
 
     private void appendColumn(
             String identifier,
-            ObjAttribute objectAttribute,
+            ObjAttribute property,
             DbAttribute column,
+            Map<String, String> fields,
             String javaType) {
 
         DbEntity table = (DbEntity) column.getEntity();
         String alias = context.getTableAlias(identifier, table.getFullyQualifiedName());
         String columnName = alias + "." + column.getName();
-        String columnLabel = objectAttribute != null ? objectAttribute
-                .getDbAttributePath() : column.getName();
 
         Set<String> columns = getColumns();
 
@@ -176,11 +189,20 @@
                     javaType = TypesMapping.getJavaBySqlType(column.getType());
                 }
 
+                String columnLabel = fields.get(property != null ? property
+                        .getDbAttributePath() : column.getName());
+
                 // TODO: andrus 6/27/2007 - the last parameter is an unofficial "jdbcType"
                 // pending CAY-813 implementation, switch to #column directive
-                context.append("' '").append(javaType).append("' '").append(
-                        column.getName()).append("' '").append(columnLabel).append(
-                        "' " + column.getType()).append(")");
+                context
+                        .append("' '")
+                        .append(javaType)
+                        .append("' '")
+                        .append(columnLabel)
+                        .append("' '")
+                        .append(columnLabel)
+                        .append("' " + column.getType())
+                        .append(")");
             }
         }
     }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java?rev=628929&r1=628928&r2=628929&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java Mon Feb 18 16:02:53 2008
@@ -29,6 +29,7 @@
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.query.EntityResult;
 import org.apache.cayenne.query.SQLResultSetMapping;
 import org.apache.cayenne.query.SQLTemplate;
 import org.apache.cayenne.reflect.ClassDescriptor;
@@ -50,7 +51,7 @@
     private Map<String, Object> boundParameters;
     private Map<String, Object> attributes;
     private Map<String, String> idAliases;
-    private int columnAliasPosition;
+    private int resultDescriptorPosition;
     private boolean usingAliases;
     private List<StringBuilder> bufferStack;
     private List<StringBuilder> bufferChain;
@@ -374,6 +375,20 @@
     }
 
     /**
+     * Returns a positional EntityResult, incrementing position index on each call.
+     */
+    EntityResult nextEntityResult() {
+
+        SQLResultSetMapping resultSetMapping = compiledExpression.getResultSetMapping();
+        if (resultSetMapping == null) {
+            throw new EJBQLException(
+                    "No result set mapping exists for expression, can't map EntityResult");
+        }
+
+        return resultSetMapping.getEntityResult(resultDescriptorPosition++);
+    }
+
+    /**
      * Returns a positional column alias, incrementing position index on each call.
      */
     String nextColumnAlias() {
@@ -384,7 +399,7 @@
                     "No result set mapping exists for expression, can't map column aliases");
         }
 
-        return resultSetMapping.getColumnResults().get(columnAliasPosition++);
+        return resultSetMapping.getColumnResult(resultDescriptorPosition++);
     }
 
     boolean isAppendingResultColumns() {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java?rev=628929&r1=628928&r2=628929&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java Mon Feb 18 16:02:53 2008
@@ -21,19 +21,33 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
 import org.apache.cayenne.ejbql.EJBQLCompiledExpression;
 import org.apache.cayenne.ejbql.EJBQLException;
 import org.apache.cayenne.ejbql.EJBQLExpression;
 import org.apache.cayenne.ejbql.EJBQLExpressionVisitor;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.map.ObjAttribute;
 import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.query.EntityResult;
 import org.apache.cayenne.query.SQLResultSetMapping;
 import org.apache.cayenne.reflect.ArcProperty;
+import org.apache.cayenne.reflect.AttributeProperty;
 import org.apache.cayenne.reflect.ClassDescriptor;
 import org.apache.cayenne.reflect.Property;
+import org.apache.cayenne.reflect.PropertyVisitor;
+import org.apache.cayenne.reflect.ToManyProperty;
+import org.apache.cayenne.reflect.ToOneProperty;
 
 /**
  * Produces an {@link EJBQLCompiledExpression} out of an EJBQL expression tree.
@@ -56,7 +70,7 @@
     private EJBQLExpressionVisitor joinVisitor;
     private EJBQLExpressionVisitor pathVisitor;
     private EJBQLExpressionVisitor rootDescriptorVisitor;
-    private SQLResultSetMapping resultSetMapping;
+    private List<Object> resultSetMappings;
 
     Compiler(EntityResolver resolver) {
         this.resolver = resolver;
@@ -110,11 +124,96 @@
         compiled.setRootId(rootId);
         compiled.setDescriptorsById(descriptorsById);
         compiled.setIncomingById(incomingById);
-        compiled.setResultSetMapping(resultSetMapping);
+
+        if (resultSetMappings != null) {
+            SQLResultSetMapping mapping = new SQLResultSetMapping();
+
+            for (int i = 0; i < resultSetMappings.size(); i++) {
+                Object nextMapping = resultSetMappings.get(i);
+                if (nextMapping instanceof String) {
+                    mapping.addColumnResult((String) nextMapping);
+                }
+                else if (nextMapping instanceof EJBQLExpression) {
+                    mapping.addEntityResult(compileEntityResult(
+                            (EJBQLExpression) nextMapping,
+                            i));
+                }
+            }
+
+            compiled.setResultSetMapping(mapping);
+        }
 
         return compiled;
     }
 
+    private EntityResult compileEntityResult(EJBQLExpression expression, int position) {
+        String id = expression.getText().toLowerCase();
+        ClassDescriptor descriptor = descriptorsById.get(id);
+        final EntityResult entityResult = new EntityResult(descriptor.getObjectClass());
+        final String prefix = "ec" + position + "_";
+        final int[] index = {
+            0
+        };
+
+        final Set<String> visited = new HashSet<String>();
+
+        PropertyVisitor visitor = new PropertyVisitor() {
+
+            public boolean visitAttribute(AttributeProperty property) {
+                ObjAttribute oa = property.getAttribute();
+                if (visited.add(oa.getDbAttributePath())) {
+                    entityResult.addObjectField(
+                            oa.getEntity().getName(),
+                            oa.getName(),
+                            prefix + index[0]++);
+                }
+                return true;
+            }
+
+            public boolean visitToMany(ToManyProperty property) {
+                return true;
+            }
+
+            public boolean visitToOne(ToOneProperty property) {
+                ObjRelationship rel = property.getRelationship();
+                DbRelationship dbRel = rel.getDbRelationships().get(0);
+
+                for (DbJoin join : dbRel.getJoins()) {
+                    DbAttribute src = join.getSource();
+                    if (src.isForeignKey() && visited.add(src.getName())) {
+                        entityResult.addDbField(src.getName(), prefix + index[0]++);
+                    }
+                }
+
+                return true;
+            }
+        };
+
+        // EJBQL queries are polymorphic by definition - there is no distinction between
+        // inheritance/no-inheritance fetch
+        descriptor.visitAllProperties(visitor);
+
+        // append id columns ... (some may have been appended already via relationships)
+        DbEntity table = descriptor.getEntity().getDbEntity();
+        for (DbAttribute pk : table.getPrimaryKeys()) {
+            if (visited.add(pk.getName())) {
+                entityResult.addDbField(pk.getName(), prefix + index[0]++);
+            }
+        }
+
+        // append inheritance discriminator columns...
+        Iterator<DbAttribute> discriminatorColumns = descriptor.getDiscriminatorColumns();
+        while (discriminatorColumns.hasNext()) {
+            DbAttribute column = discriminatorColumns.next();
+
+            if (visited.add(column.getName())) {
+                entityResult.addDbField(column.getName(), prefix + index[0]++);
+            }
+        }
+
+        return entityResult;
+    }
+
     private void addPath(EJBQLPath path) {
         if (paths == null) {
             paths = new ArrayList<EJBQLPath>();
@@ -329,6 +428,7 @@
         public boolean visitIdentifier(EJBQLExpression expression) {
             if (appendingResultColumns) {
                 rootId = normalizeIdPath(expression.getText());
+                addEntityResult(expression);
             }
             return false;
         }
@@ -346,14 +446,25 @@
             return false;
         }
 
+        private void addEntityResult(EJBQLExpression expression) {
+            if (appendingResultColumns) {
+                if (resultSetMappings == null) {
+                    resultSetMappings = new ArrayList<Object>();
+                }
+
+                // defer EntityResult creation until we resolve all ids...
+                resultSetMappings.add(expression);
+            }
+        }
+
         private void addResultSetColumn() {
             if (appendingResultColumns) {
-                if (resultSetMapping == null) {
-                    resultSetMapping = new SQLResultSetMapping();
+                if (resultSetMappings == null) {
+                    resultSetMappings = new ArrayList<Object>();
                 }
 
-                String column = "sc" + resultSetMapping.getColumnResults().size();
-                resultSetMapping.addColumnResult(column);
+                String column = "sc" + resultSetMappings.size();
+                resultSetMappings.add(column);
             }
         }
     }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/EntityResult.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/EntityResult.java?rev=628929&r1=628928&r2=628929&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/EntityResult.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/EntityResult.java Mon Feb 18 16:02:53 2008
@@ -19,8 +19,10 @@
 package org.apache.cayenne.query;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.cayenne.map.EntityResolver;
 import org.apache.cayenne.map.ObjAttribute;
@@ -38,7 +40,7 @@
 
     protected String entityName;
     protected Class<?> entityClass;
-    protected List<FieldResult> fields;
+    protected Collection<FieldResult> fields;
 
     public EntityResult(Class<?> entityClass) {
         this.entityClass = entityClass;
@@ -49,43 +51,38 @@
     }
 
     public ClassDescriptor getClassDescriptor(EntityResolver resolver) {
-        return resolver.getClassDescriptor(getEntity(resolver).getName());
+        return resolver.getClassDescriptor(getRootEntity(resolver).getName());
     }
 
     /**
-     * Returns entity result fields normalized to represent DbAttributes.
+     * Returns a map of result column names to attribute db paths from the root entity.
      */
-    public FieldResult[] getDbFields(EntityResolver resolver) {
-        FieldResult[] fields = (this.fields != null)
-                ? new FieldResult[this.fields.size()]
-                : new FieldResult[0];
-        ObjEntity entity = null;
-
-        for (int i = 0; i < fields.length; i++) {
-            FieldResult field = this.fields.get(i);
-
-            if (!field.isDbAttribute()) {
-                if (entity == null) {
-                    entity = getEntity(resolver);
-                }
+    public Map<String, String> getDbFields(EntityResolver resolver) {
 
-                ObjAttribute attribute = (ObjAttribute) entity.getAttribute(field
-                        .getAttributeName());
+        if (this.fields == null) {
+            return Collections.EMPTY_MAP;
+        }
+
+        Map<String, String> dbFields = new HashMap<String, String>();
+        for (FieldResult field : fields) {
 
-                // TODO: andrus 2/8/2008 - flattened attributes support
-                field = new FieldResult(
-                        attribute.getDbAttributeName(),
-                        field.getColumn(),
-                        true);
+            if (field.isDbAttribute()) {
+                dbFields.put(field.getAttributeName(), field.getColumn());
             }
+            else {
+                ObjEntity entity = field.getEntityName() != null ? resolver
+                        .getObjEntity(field.getEntityName()) : getRootEntity(resolver);
 
-            fields[i] = field;
+                ObjAttribute attribute = (ObjAttribute) entity.getAttribute(field
+                        .getAttributeName());
+                dbFields.put(attribute.getDbAttributePath(), field.getColumn());
+            }
         }
 
-        return fields;
+        return dbFields;
     }
 
-    public ObjEntity getEntity(EntityResolver resolver) {
+    public ObjEntity getRootEntity(EntityResolver resolver) {
         if (entityName != null) {
             return resolver.getObjEntity(entityName);
         }
@@ -97,12 +94,26 @@
         }
     }
 
+    /**
+     * Adds a result set column mapping for a single object property of the root entity.
+     */
     public void addObjectField(String attributeName, String column) {
-        addField(new FieldResult(attributeName, column, false));
+        addField(new FieldResult(null, attributeName, column, false));
     }
 
+    /**
+     * Adds a result set column mapping for a single object property of a specified entity
+     * that may differ from the root entity if inheritance is involved.
+     */
+    public void addObjectField(String entityName, String attributeName, String column) {
+        addField(new FieldResult(entityName, attributeName, column, false));
+    }
+
+    /**
+     * Adds a result set column mapping for a single DbAttribute.
+     */
     public void addDbField(String dbAttributeName, String column) {
-        addField(new FieldResult(dbAttributeName, column, true));
+        addField(new FieldResult(null, dbAttributeName, column, true));
     }
 
     void addField(FieldResult field) {
@@ -121,7 +132,7 @@
         return entityClass;
     }
 
-    public List<FieldResult> getFields() {
+    public Collection<FieldResult> getFields() {
         return fields != null ? fields : Collections.EMPTY_LIST;
     }
 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/FieldResult.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/FieldResult.java?rev=628929&r1=628928&r2=628929&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/FieldResult.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/FieldResult.java Mon Feb 18 16:02:53 2008
@@ -27,18 +27,26 @@
  * @since 3.0
  * @author Andrus Adamchik
  */
-public class FieldResult {
+class FieldResult {
 
+    protected String entityName;
     protected String attributeName;
     protected String column;
     protected boolean dbAttribute;
 
-    public FieldResult(String attributeName, String column, boolean dbAttribute) {
+    FieldResult(String entityName, String attributeName, String column,
+            boolean dbAttribute) {
+        
+        this.entityName = entityName;
         this.attributeName = attributeName;
         this.column = column;
         this.dbAttribute = dbAttribute;
     }
 
+    public String getEntityName() {
+        return entityName;
+    }
+    
     public String getAttributeName() {
         return attributeName;
     }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/SQLResultSetMapping.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/SQLResultSetMapping.java?rev=628929&r1=628928&r2=628929&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/SQLResultSetMapping.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/SQLResultSetMapping.java Mon Feb 18 16:02:53 2008
@@ -35,8 +35,7 @@
 public class SQLResultSetMapping {
 
     protected String name;
-    protected List<EntityResult> entityResults;
-    protected List<String> columnResults;
+    protected List<Object> resultDescriptors;
 
     public SQLResultSetMapping() {
 
@@ -54,33 +53,96 @@
         this.name = name;
     }
 
-    public List<EntityResult> getEntityResults() {
-        return entityResults != null ? entityResults : Collections.EMPTY_LIST;
+    /**
+     * Returns a list of result descriptors. Column descriptors are returned as Strings,
+     * entity descriptors - as {@link EntityResult}.
+     */
+    public List<Object> getResultDescriptors() {
+        return resultDescriptors != null ? resultDescriptors : Collections.EMPTY_LIST;
     }
 
-    public void addEntityResult(EntityResult entityResult) {
-        if (entityResults == null) {
-            entityResults = new ArrayList<EntityResult>(3);
+    public int[] getEntityResultPositions() {
+        if (resultDescriptors == null) {
+            return new int[0];
+        }
+
+        int[] positions = new int[resultDescriptors.size()];
+        int j = 0;
+        for (int i = 0; i < positions.length; i++) {
+            if (resultDescriptors.get(i) instanceof EntityResult) {
+                positions[j++] = i;
+            }
         }
-        
-        entityResults.add(entityResult);
+
+        int[] trimmed = new int[j];
+        System.arraycopy(positions, 0, trimmed, 0, j);
+        return trimmed;
     }
 
-    /**
-     * Returns a collection of mapped columns.
-     */
-    public List<String> getColumnResults() {
-        return columnResults != null ? columnResults : Collections.EMPTY_LIST;
+    public int[] getColumnResultPositions() {
+        if (resultDescriptors == null) {
+            return new int[0];
+        }
+
+        int[] positions = new int[resultDescriptors.size()];
+        int j = 0;
+        for (int i = 0; i < positions.length; i++) {
+            if (resultDescriptors.get(i) instanceof String) {
+                positions[j++] = i;
+            }
+        }
+
+        int[] trimmed = new int[j];
+        System.arraycopy(positions, 0, trimmed, 0, j);
+        return trimmed;
+    }
+
+    public EntityResult getEntityResult(int position) {
+        if (resultDescriptors == null) {
+            throw new IndexOutOfBoundsException("Invalid EntityResult index: " + position);
+        }
+
+        Object result = resultDescriptors.get(position);
+        if (result instanceof EntityResult) {
+            return (EntityResult) result;
+        }
+
+        throw new IllegalArgumentException("Result at position "
+                + position
+                + " is not an entity result");
+    }
+
+    public String getColumnResult(int position) {
+        if (resultDescriptors == null) {
+            throw new IndexOutOfBoundsException("Invalid column index: " + position);
+        }
+
+        Object result = resultDescriptors.get(position);
+        if (result instanceof String) {
+            return (String) result;
+        }
+
+        throw new IllegalArgumentException("Result at position "
+                + position
+                + " is not a column result");
+    }
+
+    public void addEntityResult(EntityResult entityResult) {
+        if (resultDescriptors == null) {
+            resultDescriptors = new ArrayList<Object>(3);
+        }
+
+        resultDescriptors.add(entityResult);
     }
 
     /**
      * Adds a result set column name to the mapping.
      */
     public void addColumnResult(String column) {
-        if (columnResults == null) {
-            columnResults = new ArrayList<String>(3);
+        if (resultDescriptors == null) {
+            resultDescriptors = new ArrayList<Object>(3);
         }
 
-        columnResults.add(column);
+        resultDescriptors.add(column);
     }
 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLArrayResultTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLArrayResultTest.java?rev=628929&r1=628928&r2=628929&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLArrayResultTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLArrayResultTest.java Mon Feb 18 16:02:53 2008
@@ -67,24 +67,24 @@
     }
 
     public void testSQLResultSetMappingMixed() throws Exception {
-//        createTestData("prepare");
-//
-//        String ejbql = "SELECT count(p), a, sum(p.estimatedPrice) "
-//                + "FROM Artist a LEFT JOIN a.paintingArray p "
-//                + "GROUP BY a ORDER BY a.artistName";
-//
-//        EJBQLQuery query = new EJBQLQuery(ejbql);
-//
-//        List objects = createDataContext().performQuery(query);
-//        assertEquals(4, objects.size());
-//
-//        Object o1 = objects.get(0);
-//        assertTrue("Expected Object[]: " + o1, o1 instanceof Object[]);
-//        Object[] array1 = (Object[]) o1;
-//        assertEquals(3, array1.length);
-//
-//        assertEquals(new Long(1), array1[0]);
-//        assertTrue("Expected Artist, got: " + array1[1], array1[1] instanceof Artist);
-//        assertEquals(new BigDecimal(3000), array1[1]);
+        createTestData("prepare");
+
+        String ejbql = "SELECT count(p), a, sum(p.estimatedPrice) "
+                + "FROM Artist a LEFT JOIN a.paintingArray p "
+                + "GROUP BY a ORDER BY a.artistName";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+
+        List objects = createDataContext().performQuery(query);
+        assertEquals(4, objects.size());
+
+        Object o1 = objects.get(0);
+        assertTrue("Expected Object[]: " + o1, o1 instanceof Object[]);
+        Object[] array1 = (Object[]) o1;
+        assertEquals(3, array1.length);
+
+        assertEquals(new Long(1), array1[0]);
+        assertTrue("Expected Artist, got: " + array1[1], array1[1] instanceof Artist);
+        assertEquals(new BigDecimal(3000), array1[2]);
     }
 }

Modified: cayenne/main/trunk/itests/jpa-chapter3/src/main/java/org/apache/cayenne/jpa/itest/ch3/entity/SimpleEntity.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/itests/jpa-chapter3/src/main/java/org/apache/cayenne/jpa/itest/ch3/entity/SimpleEntity.java?rev=628929&r1=628928&r2=628929&view=diff
==============================================================================
--- cayenne/main/trunk/itests/jpa-chapter3/src/main/java/org/apache/cayenne/jpa/itest/ch3/entity/SimpleEntity.java (original)
+++ cayenne/main/trunk/itests/jpa-chapter3/src/main/java/org/apache/cayenne/jpa/itest/ch3/entity/SimpleEntity.java Mon Feb 18 16:02:53 2008
@@ -18,10 +18,15 @@
  ****************************************************************/
 package org.apache.cayenne.jpa.itest.ch3.entity;
 
+import javax.persistence.ColumnResult;
 import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.SqlResultSetMapping;
 
 @Entity
+@SqlResultSetMapping(name = "rs1", columns = {
+        @ColumnResult(name = "X"), @ColumnResult(name = "Y")
+})
 public class SimpleEntity {
 
     @Id
@@ -31,7 +36,7 @@
     public int idField() {
         return id;
     }
-    
+
     public void updateIdField(int id) {
         this.id = id;
     }

Added: cayenne/main/trunk/itests/jpa-chapter3/src/test/java/org/apache/cayenne/jpa/itest/ch3/_3_6_1_QueryAPITest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/itests/jpa-chapter3/src/test/java/org/apache/cayenne/jpa/itest/ch3/_3_6_1_QueryAPITest.java?rev=628929&view=auto
==============================================================================
--- cayenne/main/trunk/itests/jpa-chapter3/src/test/java/org/apache/cayenne/jpa/itest/ch3/_3_6_1_QueryAPITest.java (added)
+++ cayenne/main/trunk/itests/jpa-chapter3/src/test/java/org/apache/cayenne/jpa/itest/ch3/_3_6_1_QueryAPITest.java Mon Feb 18 16:02:53 2008
@@ -0,0 +1,116 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.jpa.itest.ch3;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.NonUniqueResultException;
+import javax.persistence.Query;
+
+import org.apache.cayenne.itest.jpa.EntityManagerCase;
+import org.apache.cayenne.jpa.itest.ch3.entity.SimpleEntity;
+
+public class _3_6_1_QueryAPITest extends EntityManagerCase {
+
+    public void testGetResultListEntity() throws Exception {
+        getDbHelper().deleteAll("SimpleEntity");
+        getTableHelper("SimpleEntity").deleteAll().setColumns("id", "property1").insert(
+                1,
+                "X").insert(2, "Y");
+
+        EntityManager em = getEntityManager();
+        Query query = em.createQuery("SELECT a FROM SimpleEntity a ORDER BY a.property1");
+
+        List result = query.getResultList();
+        assertNotNull(result);
+        assertEquals(2, result.size());
+        assertTrue(result.get(0) instanceof SimpleEntity);
+    }
+
+    public void testGetResultListScalar() throws Exception {
+        getDbHelper().deleteAll("SimpleEntity");
+        getTableHelper("SimpleEntity").deleteAll().setColumns("id", "property1").insert(
+                1,
+                "X").insert(2, "Y");
+
+        EntityManager em = getEntityManager();
+        Query query = em.createQuery("SELECT count(a) FROM SimpleEntity a");
+
+        List result = query.getResultList();
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertTrue(result.get(0) instanceof Long);
+        assertEquals(2, ((Long) result.get(0)).intValue());
+    }
+
+    public void testGetResultListMixed() throws Exception {
+        getDbHelper().deleteAll("SimpleEntity");
+        getTableHelper("SimpleEntity").deleteAll().setColumns("id", "property1").insert(
+                1,
+                "X").insert(2, "Y");
+
+        EntityManager em = getEntityManager();
+        Query query = em
+                .createQuery("SELECT a, a.id FROM SimpleEntity a ORDER BY a.property1");
+
+        List result = query.getResultList();
+        assertNotNull(result);
+        assertEquals(2, result.size());
+        assertTrue(result.get(0) instanceof Object[]);
+
+        Object[] row0 = (Object[]) result.get(0);
+        assertEquals(2, row0.length);
+
+        assertTrue(row0[0] instanceof SimpleEntity);
+        assertEquals(1, ((Number) row0[1]).intValue());
+    }
+
+    public void testGetSingleResultListEntity() throws Exception {
+        getDbHelper().deleteAll("SimpleEntity");
+        getTableHelper("SimpleEntity").deleteAll().setColumns("id", "property1").insert(
+                1,
+                "X");
+
+        EntityManager em = getEntityManager();
+        Query query = em.createQuery("SELECT a FROM SimpleEntity a ORDER BY a.property1");
+
+        Object result = query.getSingleResult();
+        assertNotNull(result);
+        assertTrue(result instanceof SimpleEntity);
+    }
+
+    public void testGetSingleResultListEntityNonUniqueResultException() throws Exception {
+        getDbHelper().deleteAll("SimpleEntity");
+        getTableHelper("SimpleEntity").deleteAll().setColumns("id", "property1").insert(
+                1,
+                "X").insert(2, "Y");
+
+        EntityManager em = getEntityManager();
+        Query query = em.createQuery("SELECT a FROM SimpleEntity a ORDER BY a.property1");
+
+        try {
+            query.getSingleResult();
+            fail("Must have thrown NonUniqueResultException");
+        }
+        catch (NonUniqueResultException e) {
+            // expected
+        }
+    }
+}

Added: cayenne/main/trunk/itests/jpa-chapter3/src/test/java/org/apache/cayenne/jpa/itest/ch3/_3_6_6_SQLQueriesTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/itests/jpa-chapter3/src/test/java/org/apache/cayenne/jpa/itest/ch3/_3_6_6_SQLQueriesTest.java?rev=628929&view=auto
==============================================================================
--- cayenne/main/trunk/itests/jpa-chapter3/src/test/java/org/apache/cayenne/jpa/itest/ch3/_3_6_6_SQLQueriesTest.java (added)
+++ cayenne/main/trunk/itests/jpa-chapter3/src/test/java/org/apache/cayenne/jpa/itest/ch3/_3_6_6_SQLQueriesTest.java Mon Feb 18 16:02:53 2008
@@ -0,0 +1,68 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.jpa.itest.ch3;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.cayenne.itest.jpa.EntityManagerCase;
+import org.apache.cayenne.jpa.itest.ch3.entity.SimpleEntity;
+
+public class _3_6_6_SQLQueriesTest extends EntityManagerCase {
+
+    public void testNativeEntityQuery() throws Exception {
+        getDbHelper().deleteAll("SimpleEntity");
+        getTableHelper("SimpleEntity").deleteAll().setColumns("id", "property1").insert(
+                1,
+                "X").insert(2, "Y");
+
+        EntityManager em = getEntityManager();
+        Query query = em.createNativeQuery(
+                "SELECT id, property1 FROM SimpleEntity ORDER BY property1",
+                SimpleEntity.class);
+
+        // TODO: andrus 2/18/2008 - this fails because of wrong column name
+        // capitalization... need to figure a portable solution
+
+        // List result = query.getResultList();
+        // assertNotNull(result);
+        // assertEquals(2, result.size());
+        // assertTrue(result.get(0) instanceof SimpleEntity);
+    }
+
+    public void testNativeEntityQueryMappedResult() throws Exception {
+        getDbHelper().deleteAll("SimpleEntity");
+        getTableHelper("SimpleEntity").deleteAll().setColumns("id", "property1").insert(
+                1,
+                "X").insert(2, "Y");
+
+        // TODO: andrus 2/18/2008 map named JPA SQLResultSetMappings to Cayenne
+        // EntityManager em = getEntityManager();
+        // Query query = em.createNativeQuery(
+        // "SELECT ID as X, ID + 5 as Y, ID + 6 as Z FROM SimpleEntity ORDER BY ID",
+        // "rs1");
+        //
+        // List result = query.getResultList();
+        // assertNotNull(result);
+        // assertEquals(2, result.size());
+        // assertTrue(result.get(0) instanceof Object[]);
+    }
+}

Modified: cayenne/main/trunk/itests/jpa-chapter4/src/test/java/org/apache/cayenne/jpa/itest/ch4/_4_2_1_SelectStatementTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/itests/jpa-chapter4/src/test/java/org/apache/cayenne/jpa/itest/ch4/_4_2_1_SelectStatementTest.java?rev=628929&r1=628928&r2=628929&view=diff
==============================================================================
--- cayenne/main/trunk/itests/jpa-chapter4/src/test/java/org/apache/cayenne/jpa/itest/ch4/_4_2_1_SelectStatementTest.java (original)
+++ cayenne/main/trunk/itests/jpa-chapter4/src/test/java/org/apache/cayenne/jpa/itest/ch4/_4_2_1_SelectStatementTest.java Mon Feb 18 16:02:53 2008
@@ -43,22 +43,21 @@
 		assertEquals("XXX", ((SimpleEntity) result.get(0)).getProperty1());
 	}
 
-	// TODO: andrus, 3/11/2007 - this fails.
 	public void testSelectFromWhere() throws Exception {
-		// getDbHelper().deleteAll("SimpleEntity");
-		//
-		// getDbHelper().insert("SimpleEntity",
-		// new String[] { "id", "property1" }, new Object[] { 15, "XXX" });
-		// getDbHelper().insert("SimpleEntity",
-		// new String[] { "id", "property1" }, new Object[] { 16, "YYY" });
-		//
-		// Query query = getEntityManager().createQuery(
-		// "select x from SimpleEntity x where x.property1 = 'YYY'");
-		// assertNotNull(query);
-		// List result = query.getResultList();
-		// assertNotNull(result);
-		// assertEquals(1, result.size());
-		// assertTrue(result.get(0) instanceof SimpleEntity);
-		// assertEquals("YYY", ((SimpleEntity) result.get(0)).getProperty1());
+		getDbHelper().deleteAll("SimpleEntity");
+
+		getDbHelper().insert("SimpleEntity",
+				new String[] { "id", "property1" }, new Object[] { 15, "XXX" });
+		getDbHelper().insert("SimpleEntity",
+				new String[] { "id", "property1" }, new Object[] { 16, "YYY" });
+
+		Query query = getEntityManager().createQuery(
+				"select x from SimpleEntity x where x.property1 = 'YYY'");
+		assertNotNull(query);
+		List result = query.getResultList();
+		assertNotNull(result);
+		assertEquals(1, result.size());
+		assertTrue(result.get(0) instanceof SimpleEntity);
+		assertEquals("YYY", ((SimpleEntity) result.get(0)).getProperty1());
 	}
 }



Mime
View raw message