You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by hw...@apache.org on 2015/12/30 18:21:04 UTC

deltaspike git commit: DELTASPIKE-1052 simplified EntityGraphHelper

Repository: deltaspike
Updated Branches:
  refs/heads/master cf3fa2483 -> e79b665a4


DELTASPIKE-1052 simplified EntityGraphHelper

Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/e79b665a
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/e79b665a
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/e79b665a

Branch: refs/heads/master
Commit: e79b665a4addecec4d97105d49dbda6fdcbbb631
Parents: cf3fa24
Author: Harald Wellmann <hw...@apache.org>
Authored: Wed Dec 30 18:20:58 2015 +0100
Committer: Harald Wellmann <hw...@apache.org>
Committed: Wed Dec 30 18:20:58 2015 +0100

----------------------------------------------------------------------
 .../apache/deltaspike/data/api/EntityGraph.java |   2 +-
 .../data/impl/graph/EntityGraphHelper.java      | 131 +++++++++----------
 .../impl/handler/CdiQueryInvocationContext.java |  14 +-
 .../test/ee7/graph/HouseRepositoryTest.java     |   3 +-
 4 files changed, 62 insertions(+), 88 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e79b665a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityGraph.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityGraph.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityGraph.java
index 53b157f..1616263 100644
--- a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityGraph.java
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityGraph.java
@@ -27,7 +27,7 @@ import java.lang.annotation.Target;
  * Defines an entity graph to be applied to a query. This annotation can be added to any query
  * method of a repository class.
  * <p>
- * The arguments {@code value} and {@code paths} are mutually exclusive. If {@value is set}, it
+ * The arguments {@code value} and {@code paths} are mutually exclusive. If {@code value} is set, it
  * references a named entity graph defined by JPA metadata.
  * <p>
  * If {@code paths} is set, an entity graph is constructed programmatically from the list of

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e79b665a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/graph/EntityGraphHelper.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/graph/EntityGraphHelper.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/graph/EntityGraphHelper.java
index eb3b296..a006f77 100644
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/graph/EntityGraphHelper.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/graph/EntityGraphHelper.java
@@ -28,15 +28,25 @@ import java.util.List;
 import javax.persistence.EntityManager;
 
 import org.apache.deltaspike.core.util.ClassUtils;
+import org.apache.deltaspike.core.util.ExceptionUtils;
+import org.apache.deltaspike.data.api.EntityGraph;
 
+/**
+ * Helper for invoking methods related to entity graphs by reflection.
+ * <p>
+ * Reflection is required to stay compatible with JPA 2.0.
+ */
 public final class EntityGraphHelper
 {
 
     private static final Class<?> ENTITY_GRAPH_CLASS;
     private static final Class<?> SUBGRAPH_CLASS;
-    private static final Method ADD_ATTRIBUTE_NODES;
-    private static final Method ADD_SUBGRAPH;
+    private static final Method EG_ADD_ATTRIBUTE_NODES;
+    private static final Method EG_ADD_SUBGRAPH;
     private static final Method SUBGRAPH_ADD_ATTRIBUTE_NODES;
+    private static final Method SUBGRAPH_ADD_SUBGRAPH;
+    private static final Method EM_GET_ENTITY_GRAPH;
+    private static final Method EM_CREATE_ENTITY_GRAPH;
 
     static
     {
@@ -44,27 +54,30 @@ public final class EntityGraphHelper
         SUBGRAPH_CLASS = ClassUtils.tryToLoadClassForName("javax.persistence.Subgraph");
         if (ENTITY_GRAPH_CLASS == null)
         {
-            ADD_ATTRIBUTE_NODES = null;
-            ADD_SUBGRAPH = null;
+            EG_ADD_ATTRIBUTE_NODES = null;
+            EG_ADD_SUBGRAPH = null;
             SUBGRAPH_ADD_ATTRIBUTE_NODES = null;
+            SUBGRAPH_ADD_SUBGRAPH = null;
+            EM_GET_ENTITY_GRAPH = null;
+            EM_CREATE_ENTITY_GRAPH = null;
         }
         else
         {
             try
             {
-                ADD_ATTRIBUTE_NODES = ENTITY_GRAPH_CLASS.getMethod("addAttributeNodes",
+                EG_ADD_ATTRIBUTE_NODES = ENTITY_GRAPH_CLASS.getMethod("addAttributeNodes",
                     String[].class);
-                ADD_SUBGRAPH = ENTITY_GRAPH_CLASS.getMethod("addSubgraph", String.class);
+                EG_ADD_SUBGRAPH = ENTITY_GRAPH_CLASS.getMethod("addSubgraph", String.class);
                 SUBGRAPH_ADD_ATTRIBUTE_NODES = SUBGRAPH_CLASS.getMethod("addAttributeNodes",
                     String[].class);
+                SUBGRAPH_ADD_SUBGRAPH = SUBGRAPH_CLASS.getMethod("addSubgraph", String.class);
+                EM_GET_ENTITY_GRAPH = EntityManager.class.getMethod("getEntityGraph", String.class);
+                EM_CREATE_ENTITY_GRAPH = EntityManager.class.getMethod("createEntityGraph",
+                    Class.class);
             }
             catch (NoSuchMethodException e)
             {
-                throw new EntityGraphException(e.getMessage(), e.getCause());
-            }
-            catch (SecurityException e)
-            {
-                throw new EntityGraphException(e.getMessage(), e.getCause());
+                throw ExceptionUtils.throwAsRuntimeException(e);
             }
         }
     }
@@ -79,60 +92,46 @@ public final class EntityGraphHelper
         return ENTITY_GRAPH_CLASS != null;
     }
 
-    public static Object getEntityGraph(EntityManager em, String graphName)
+    /*
+     * TODO Check if this can be replaced by org.apache.deltaspike.core.util.ReflectionUtils.invokeMethod.
+     * This does not work at the moment due to an issue with exception handling in that method
+     * which needs further analysis. 
+     */
+    private static Object uncheckedInvoke(Method method, Object target, Object... args)
     {
-        ensureAvailable();
         try
         {
-            Method method = EntityManager.class.getMethod("getEntityGraph", String.class);
-            return method.invoke(em, graphName);
-        }
-        catch (NoSuchMethodException e)
-        {
-            throw new EntityGraphException("no method EntityManager.getEntityGraph()", e);
-        }
-        catch (SecurityException e)
-        {
-            throw new EntityGraphException("no access to method EntityManager.getEntityGraph()", e);
+            return method.invoke(target, args);
         }
         catch (IllegalAccessException e)
         {
-            throw new EntityGraphException("no access to method EntityManager.getEntityGraph()", e);
+            throw ExceptionUtils.throwAsRuntimeException(e);
         }
         catch (InvocationTargetException e)
         {
-            throw new EntityGraphException(e.getCause().getMessage(), e.getCause());
+            throw ExceptionUtils.throwAsRuntimeException(e.getCause());
         }
     }
 
-    public static Object createEntityGraph(EntityManager em, Class<?> entityClass)
+    public static Object getEntityGraph(EntityManager em, Class<?> entityClass, EntityGraph entityGraphAnn)
     {
         ensureAvailable();
-        try
+        String graphName = entityGraphAnn.value();
+        if (graphName.isEmpty())
         {
-            Method method = EntityManager.class.getMethod("createEntityGraph", Class.class);
-            return method.invoke(em, entityClass);
+            return buildEntityGraph(em, entityClass, entityGraphAnn.paths());
         }
-        catch (NoSuchMethodException e)
-        {
-            throw new EntityGraphException("no method EntityManager.createEntityGraph()", e);
-        }
-        catch (SecurityException e)
-        {
-            throw new EntityGraphException("no access to method EntityManager.createEntityGraph()",
-                e);
-        }
-        catch (IllegalAccessException e)
-        {
-            throw new EntityGraphException("no access to method EntityManager.createEntityGraph()",
-                e);
-        }
-        catch (InvocationTargetException e)
+        else
         {
-            throw new EntityGraphException(e.getCause().getMessage(), e.getCause());
+            return uncheckedInvoke(EM_GET_ENTITY_GRAPH, em, graphName);
         }
     }
 
+    private static Object createEntityGraph(EntityManager em, Class<?> entityClass)
+    {
+        return uncheckedInvoke(EM_CREATE_ENTITY_GRAPH, em, entityClass);
+    }
+
     private static void ensureAvailable()
     {
         if (!isAvailable())
@@ -142,52 +141,40 @@ public final class EntityGraphHelper
         }
     }
 
-    public static Object addSubgraph(Object entityGraph, String attributeName)
+    private static Object addSubgraph(Object graph, String attributeName)
     {
-        try
+        if (ENTITY_GRAPH_CLASS.isInstance(graph))
         {
-            return ADD_SUBGRAPH.invoke(entityGraph, attributeName);
+            return uncheckedInvoke(EG_ADD_SUBGRAPH, graph, attributeName);
         }
-        catch (IllegalAccessException e)
+        else if (SUBGRAPH_CLASS.isInstance(graph))
         {
-            throw new EntityGraphException("no access to method EntityGraph.addSubgraph()", e);
-        }
-        catch (InvocationTargetException e)
-        {
-            throw new EntityGraphException(e.getCause().getMessage(), e.getCause());
+            return uncheckedInvoke(SUBGRAPH_ADD_SUBGRAPH, graph, attributeName);
         }
+        return null;
     }
 
-    public static void addAttributeNodes(Object graph, String attributeName)
+    private static void addAttributeNodes(Object graph, String attributeName)
     {
-        try
+        if (ENTITY_GRAPH_CLASS.isInstance(graph))
         {
-            if (ENTITY_GRAPH_CLASS.isInstance(graph))
-            {
-                ADD_ATTRIBUTE_NODES.invoke(graph, new Object[] { new String[] { attributeName } });
-            }
-            else if (SUBGRAPH_CLASS.isInstance(graph))
-            {
-                SUBGRAPH_ADD_ATTRIBUTE_NODES.invoke(graph,
-                    new Object[] { new String[] { attributeName } });
-            }
+            uncheckedInvoke(EG_ADD_ATTRIBUTE_NODES, graph,
+                new Object[] { new String[] { attributeName } });
         }
-        catch (IllegalAccessException e)
-        {
-            throw new EntityGraphException("no access to method addAttributeNodes()", e);
-        }
-        catch (InvocationTargetException e)
+        else if (SUBGRAPH_CLASS.isInstance(graph))
         {
-            throw new EntityGraphException(e.getCause().getMessage(), e.getCause());
+            uncheckedInvoke(SUBGRAPH_ADD_ATTRIBUTE_NODES, graph,
+                new Object[] { new String[] { attributeName } });
         }
     }
 
-    public static Object buildEntityGraph(EntityManager em, Class<?> entityClass,
+    private static Object buildEntityGraph(EntityManager em, Class<?> entityClass,
         String[] attributePaths)
     {
         Object graph = createEntityGraph(em, entityClass);
         List<String> paths = new ArrayList<String>(Arrays.asList(attributePaths));
 
+        // handle longest paths first
         Collections.sort(paths);
         Collections.reverse(paths);
 

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e79b665a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryInvocationContext.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryInvocationContext.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryInvocationContext.java
index 40686f0..e74e022 100644
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryInvocationContext.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryInvocationContext.java
@@ -322,21 +322,10 @@ public class CdiQueryInvocationContext implements QueryInvocationContext
             return;
         }
         
-        String graphName = entityGraphAnn.value();
-        Object graph;
-        if (graphName.isEmpty())
-        {
-            graph = EntityGraphHelper.buildEntityGraph(getEntityManager(), entityClass, entityGraphAnn.paths());
-        }
-        else
-        {
-            graph = EntityGraphHelper.getEntityGraph(getEntityManager(), graphName);
-        }
+        Object graph = EntityGraphHelper.getEntityGraph(getEntityManager(), entityClass, entityGraphAnn);
         query.setHint(entityGraphAnn.type().getHintName(), graph);
     }
 
-    
-
     private boolean countCheck(Object entity)
     {
         StringBuilder jpql = new StringBuilder("SELECT COUNT(e) FROM " + getEntityClass()
@@ -354,5 +343,4 @@ public class CdiQueryInvocationContext implements QueryInvocationContext
         }
         return false;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e79b665a/deltaspike/modules/data/test-ee7/src/test/java/org/apache/deltaspike/data/test/ee7/graph/HouseRepositoryTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/test-ee7/src/test/java/org/apache/deltaspike/data/test/ee7/graph/HouseRepositoryTest.java b/deltaspike/modules/data/test-ee7/src/test/java/org/apache/deltaspike/data/test/ee7/graph/HouseRepositoryTest.java
index 73a3d18..370df98 100644
--- a/deltaspike/modules/data/test-ee7/src/test/java/org/apache/deltaspike/data/test/ee7/graph/HouseRepositoryTest.java
+++ b/deltaspike/modules/data/test-ee7/src/test/java/org/apache/deltaspike/data/test/ee7/graph/HouseRepositoryTest.java
@@ -35,7 +35,6 @@ import javax.persistence.PersistenceUnitUtil;
 import javax.transaction.UserTransaction;
 
 import org.apache.deltaspike.data.api.QueryInvocationException;
-import org.apache.deltaspike.data.impl.graph.EntityGraphException;
 import org.apache.deltaspike.data.test.ee7.domain.Flat;
 import org.apache.deltaspike.data.test.ee7.domain.Garage;
 import org.apache.deltaspike.data.test.ee7.domain.House;
@@ -131,7 +130,7 @@ public class HouseRepositoryTest
         }
         catch (QueryInvocationException e)
         {
-            assertTrue(e.getCause() instanceof EntityGraphException);
+            assertTrue(e.getCause() instanceof IllegalArgumentException);
         }
     }