You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2019/09/02 09:29:31 UTC

[cayenne] 03/03: Merge PR #404

This is an automated email from the ASF dual-hosted git repository.

ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit 1e587abe42a5d80308aa8ca76b9556da28a7b38a
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Mon Sep 2 12:29:16 2019 +0300

    Merge PR #404
---
 .../java/org/apache/cayenne/access/DataDomain.java | 11 +++++++++
 .../cayenne/access/DataDomainQueryAction.java      | 26 ++++++++++------------
 .../access/jdbc/reader/EmbeddableRowReader.java    |  2 +-
 .../translator/select/QualifierTranslator.java     |  2 +-
 .../cayenne/exp/property/EmbeddableProperty.java   |  6 +++--
 .../apache/cayenne/exp/property/PathProperty.java  |  4 +++-
 .../cayenne/exp/property/PropertyFactory.java      | 23 ++++++++++++++++++-
 7 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java
index 1b95efb..fa9d9c8 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java
@@ -32,6 +32,7 @@ import org.apache.cayenne.access.flush.DataDomainFlushAction;
 import org.apache.cayenne.access.flush.DataDomainFlushActionFactory;
 import org.apache.cayenne.cache.QueryCache;
 import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.BeforeScopeEnd;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.event.EventManager;
@@ -115,6 +116,12 @@ public class DataDomain implements QueryEngine, DataChannel {
 	@Inject
 	protected DataDomainFlushActionFactory flushActionFactory;
 
+	/**
+	 * @since 4.2
+	 */
+	@Inject
+	protected AdhocObjectFactory objectFactory;
+
 	protected Map<String, DataNode> nodes;
 	protected Map<String, DataNode> nodesByDataMapName;
 	protected DataNode defaultNode;
@@ -873,4 +880,8 @@ public class DataDomain implements QueryEngine, DataChannel {
 	TransactionManager getTransactionManager() {
 		return transactionManager;
 	}
+
+	AdhocObjectFactory getObjectFactory() {
+		return objectFactory;
+	}
 }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
index 8697160..80a861f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
@@ -29,6 +29,7 @@ import org.apache.cayenne.QueryResponse;
 import org.apache.cayenne.ResultIterator;
 import org.apache.cayenne.cache.QueryCache;
 import org.apache.cayenne.cache.QueryCacheEntryFactory;
+import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbRelationship;
@@ -75,12 +76,13 @@ class DataDomainQueryAction implements QueryRouter, OperationObserver {
 
     static final boolean DONE = true;
 
-    DataContext context;
-    DataDomain domain;
-    DataRowStore cache;
-    Query query;
-    QueryMetadata metadata;
+    final DataContext context;
+    final DataDomain domain;
+    final Query query;
+    final QueryMetadata metadata;
+    final AdhocObjectFactory objectFactory;
 
+    DataRowStore cache;
     QueryResponse response;
     GenericResponse fullResponse;
     Map<String, List<?>> prefetchResultsByPath;
@@ -102,6 +104,7 @@ class DataDomainQueryAction implements QueryRouter, OperationObserver {
         this.query = query;
         this.metadata = query.getMetaData(domain.getEntityResolver());
         this.context = (DataContext) context;
+        this.objectFactory = domain.getObjectFactory();
 
         // cache may be shared or unique for the ObjectContext
         if (context != null) {
@@ -716,19 +719,14 @@ class DataDomainQueryAction implements QueryRouter, OperationObserver {
         void convert(List<DataRow> mainRows) {
             EmbeddableResultSegment resultSegment = (EmbeddableResultSegment)metadata.getResultSetMapping().get(0);
             Embeddable embeddable = resultSegment.getEmbeddable();
-            Class<?> embeddableClass;
-            try {
-                embeddableClass = Class.forName(embeddable.getClassName());
-            } catch (Exception e) {
-                throw new CayenneRuntimeException("Unable create Embeddable class %s", e, embeddable.getClassName());
-            }
+            Class<?> embeddableClass = objectFactory.getJavaClass(embeddable.getClassName());
             List<EmbeddableObject> result = new ArrayList<>(mainRows.size());
             mainRows.forEach(dataRow -> {
                 EmbeddableObject eo;
                 try {
                     eo = (EmbeddableObject)embeddableClass.newInstance();
                 } catch (InstantiationException | IllegalAccessException e) {
-                    throw new CayenneRuntimeException("Unable create instance of Embeddable %s", e, embeddable.getClassName());
+                    throw new CayenneRuntimeException("Unable to materialize embeddable '%s'", e, embeddable.getClassName());
                 }
                 dataRow.forEach(eo::writePropertyDirectly);
                 result.add(eo);
@@ -801,8 +799,8 @@ class DataDomainQueryAction implements QueryRouter, OperationObserver {
                 } else if (mapping instanceof EmbeddableResultSegment) {
                     EmbeddableResultSegment resultSegment = (EmbeddableResultSegment)mapping;
                     Embeddable embeddable = resultSegment.getEmbeddable();
+                    Class<?> embeddableClass = objectFactory.getJavaClass(embeddable.getClassName());
                     try {
-                        Class<?> embeddableClass = Class.forName(embeddable.getClassName());
                         for(Object[] row : mainRows) {
                             DataRow dataRow = (DataRow)row[i];
                             EmbeddableObject eo = (EmbeddableObject)embeddableClass.newInstance();
@@ -810,7 +808,7 @@ class DataDomainQueryAction implements QueryRouter, OperationObserver {
                             row[i] = eo;
                         }
                     } catch (Exception e) {
-                        e.printStackTrace();
+                        throw new CayenneRuntimeException("Unable to materialize embeddable '%s'", e, embeddable.getClassName());
                     }
                 }
             }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/reader/EmbeddableRowReader.java b/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/reader/EmbeddableRowReader.java
index d9056e5..e520637 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/reader/EmbeddableRowReader.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/reader/EmbeddableRowReader.java
@@ -73,7 +73,7 @@ class EmbeddableRowReader implements RowReader<DataRow> {
             // rethrow unmodified
             throw cex;
         } catch (Exception otherex) {
-            throw new CayenneRuntimeException("Exception materializing id column.", Util.unwindException(otherex));
+            throw new CayenneRuntimeException("Exception materializing column.", Util.unwindException(otherex));
         }
     }
 }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
index c199f49..bc08469 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
@@ -285,7 +285,7 @@ class QualifierTranslator implements TraversalHandler {
             }
         }
 
-        throw new CayenneRuntimeException("Embeddable attribute ObjPath isn't matched with valid value.");
+        throw new CayenneRuntimeException("Embeddable attribute ObjPath isn't matched with a valid value.");
     }
 
     private Node createMultiAttributeMatch(Expression node, Expression parentNode, PathTranslationResult result) {
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EmbeddableProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EmbeddableProperty.java
index cb5c564..9eb151c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EmbeddableProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EmbeddableProperty.java
@@ -19,6 +19,8 @@
 
 package org.apache.cayenne.exp.property;
 
+import org.apache.cayenne.exp.Expression;
+
 /**
  * Property that represents object attribute mapped on {@link org.apache.cayenne.map.Embeddable} object.
  * @since 4.2
@@ -32,7 +34,7 @@ public class EmbeddableProperty<E> extends BaseProperty<E> implements PathProper
      * @param type       of the property
      * @see PropertyFactory#createEmbeddable(String, Class)
      */
-    protected EmbeddableProperty(String name, Class<? super E> type) {
-        super(name, null, type);
+    protected EmbeddableProperty(String name, Expression exp, Class<? super E> type) {
+        super(name, exp, type);
     }
 }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PathProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PathProperty.java
index 9746950..bc1f4aa 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PathProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PathProperty.java
@@ -155,6 +155,8 @@ public interface PathProperty<E> extends Property<E> {
      */
     default <T extends EmbeddableObject> EmbeddableProperty<T> dot(EmbeddableProperty<T> property) {
         String path = getName() + "." + property.getName();
-        return PropertyFactory.createEmbeddable(path, property.getType());
+        return PropertyFactory.createEmbeddable(path,
+                PropertyUtils.buildExp(path, getExpression().getPathAliases()),
+                property.getType());
     }
 }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java
index cf1ef6e..701ec43 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java
@@ -374,7 +374,28 @@ public class PropertyFactory {
         return createMap(name, null, keyType, entityType);
     }
 
+    /**
+     * Create property that represents embeddable
+     *
+     * @param name of the property, will be used as value for path expression
+     * @param embeddableType type of represented embeddable entity
+     * @param <T> type of represented embeddable entity
+     * @return new path property
+     */
     public static <T extends EmbeddableObject> EmbeddableProperty<T> createEmbeddable(String name, Class<T> embeddableType) {
-        return new EmbeddableProperty<>(name, embeddableType);
+        return new EmbeddableProperty<>(name, null, embeddableType);
+    }
+
+    /**
+     * Create property that represents embeddable
+     *
+     * @param name of the property, will be used as value for path expression
+     * @param exp that property will use
+     * @param embeddableType type of represented embeddable entity
+     * @param <T> type of represented embeddable entity
+     * @return new path property
+     */
+    public static <T extends EmbeddableObject> EmbeddableProperty<T> createEmbeddable(String name, Expression exp, Class<T> embeddableType) {
+        return new EmbeddableProperty<>(name, exp, embeddableType);
     }
 }