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 <[email protected]> Authored: Wed Dec 30 18:20:58 2015 +0100 Committer: Harald Wellmann <[email protected]> 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); } }
