You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by th...@apache.org on 2013/11/28 15:48:10 UTC

[2/3] git commit: DELTASPIKE-421 Optional single results.

DELTASPIKE-421 Optional single results.


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

Branch: refs/heads/master
Commit: f3c00d8c722e357faba4b0527499d9daa5216453
Parents: feba6a7
Author: Thomas Hug <Th...@ctp-consulting.com>
Authored: Fri Nov 22 14:01:37 2013 +0100
Committer: Thomas Hug <Th...@ctp-consulting.com>
Committed: Thu Nov 28 14:38:25 2013 +0100

----------------------------------------------------------------------
 .../org/apache/deltaspike/data/api/Query.java   |   6 +
 .../apache/deltaspike/data/api/QueryResult.java |  15 ++
 .../apache/deltaspike/data/api/Repository.java  |   2 +-
 .../deltaspike/data/api/SingleResultType.java   |  46 ++++++
 .../deltaspike/data/api/criteria/Criteria.java  |  14 ++
 .../data/impl/builder/part/QueryRoot.java       |  21 ++-
 .../impl/builder/result/DefaultQueryResult.java |  21 +++
 .../impl/builder/result/QueryProcessor.java     |   4 +-
 .../builder/result/QueryProcessorFactory.java   |  30 +++-
 .../data/impl/criteria/QueryCriteria.java       |  21 +++
 .../impl/handler/CdiQueryInvocationContext.java |   8 +-
 .../data/impl/handler/QueryHandler.java         |   8 +-
 .../deltaspike/data/impl/meta/MethodPrefix.java | 145 +++++++++++++++++++
 .../data/impl/meta/RepositoryComponent.java     |  10 +-
 .../data/impl/meta/RepositoryMethod.java        |  16 +-
 .../deltaspike/data/impl/QueryResultTest.java   |  49 +++++++
 .../data/impl/builder/part/QueryRootTest.java   |  20 ++-
 .../data/impl/criteria/CriteriaTest.java        |  50 +++++++
 .../data/impl/handler/QueryHandlerTest.java     |  95 ++++++++++++
 .../test/service/SimpleCriteriaRepository.java  |  14 ++
 .../data/test/service/SimpleRepository.java     |  17 ++-
 .../data/test/util/TestDeployments.java         |   3 +-
 22 files changed, 577 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Query.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Query.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Query.java
index 23970ce..e03410c 100755
--- a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Query.java
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Query.java
@@ -72,4 +72,10 @@ public @interface Query
     QueryHint[] hints() default {
     };
 
+    /**
+     * Defines how a single result query is fetched. Defaults to the JPA way with
+     * Exceptions thrown on non-single result queries.
+     */
+    SingleResultType singleResult() default SingleResultType.JPA;
+
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/QueryResult.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/QueryResult.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/QueryResult.java
index f3289a9..fce1a87 100644
--- a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/QueryResult.java
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/QueryResult.java
@@ -149,6 +149,21 @@ public interface QueryResult<E>
     E getSingleResult();
 
     /**
+     * Fetch a single result entity. Returns {@code null} if no result is found.
+     *
+     * @return                  Entity retrieved by the query, or {@code null} if no result.
+     */
+    E getOptionalResult();
+
+    /**
+     * Fetch a single result entity. Returns {@code null} if no result is found. If the
+     * query finds multiple results, it simply returns the first one found.
+     *
+     * @return                  First Entity retrieved by the query, or {@code null} if no result.
+     */
+    E getAnyResult();
+
+    /**
      * Count the result set.
      * @return                  Result count.
      */

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Repository.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Repository.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Repository.java
index 0f86131..f1a1308 100755
--- a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Repository.java
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Repository.java
@@ -47,6 +47,6 @@ public @interface Repository
      * The method prefix for method expressions. Can be adapted to
      * domain specific conventions.
      */
-    String methodPrefix() default "findBy";
+    String methodPrefix() default "";
 
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/SingleResultType.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/SingleResultType.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/SingleResultType.java
new file mode 100644
index 0000000..c2a54e8
--- /dev/null
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/SingleResultType.java
@@ -0,0 +1,46 @@
+/*
+ * 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.deltaspike.data.api;
+
+/**
+ * Defines the way a single result query is fetched.
+ */
+public enum SingleResultType
+{
+
+    /**
+     * Expects a single result, throws a {@link javax.persistence.NoResultException} or
+     * {@link javax.persistence.NonUniqueResultException} otherwise. This is the JPA
+     * default behavior.
+     */
+    JPA,
+
+    /**
+     * Expects a single result. Other than {@link SingleResultStyle#SINGLE} it returns {@code null}
+     * if no result is found.
+     */
+    OPTIONAL,
+
+    /**
+     * Returns any result, or {@code null} if nothing is found. If more than one result is found,
+     * it returns the first one from the result list.
+     */
+    ANY
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/Criteria.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/Criteria.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/Criteria.java
index 909034b..6dfedd1 100644
--- a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/Criteria.java
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/Criteria.java
@@ -55,6 +55,20 @@ public interface Criteria<C, R>
     R getSingleResult();
 
     /**
+     * Executes the query which has a single result. Returns {@code null}
+     * if there is no result.
+     * @return Entity matching the search query, or {@code null} if there is none.
+     */
+    R getOptionalResult();
+
+    /**
+     * Executes the query and returns a single result. If there are
+     * multiple results, the first received is returned.
+     * @return Entity matching the search query.
+     */
+    R getAnyResult();
+
+    /**
      * Creates a JPA query object to be executed.
      * @return A {@link TypedQuery} object ready to return results.
      */

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/QueryRoot.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/QueryRoot.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/QueryRoot.java
index 1774125..9484634 100644
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/QueryRoot.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/QueryRoot.java
@@ -28,6 +28,7 @@ import java.util.logging.Logger;
 import org.apache.deltaspike.data.impl.builder.MethodExpressionException;
 import org.apache.deltaspike.data.impl.builder.QueryBuilder;
 import org.apache.deltaspike.data.impl.builder.QueryBuilderContext;
+import org.apache.deltaspike.data.impl.meta.MethodPrefix;
 import org.apache.deltaspike.data.impl.meta.RepositoryComponent;
 
 /**
@@ -36,24 +37,24 @@ import org.apache.deltaspike.data.impl.meta.RepositoryComponent;
 public class QueryRoot extends QueryPart
 {
 
-    public static final QueryRoot UNKNOWN_ROOT = new QueryRoot("null-object", "");
+    public static final QueryRoot UNKNOWN_ROOT = new QueryRoot("null-object", new MethodPrefix("", null));
 
     private static final Logger log = Logger.getLogger(QueryRoot.class.getName());
 
     private final String entityName;
-    private final String queryPrefix;
+    private final MethodPrefix methodPrefix;
 
     private String jpqlQuery;
 
-    protected QueryRoot(String entityName, String queryPrefix)
+    protected QueryRoot(String entityName, MethodPrefix methodPrefix)
     {
         this.entityName = entityName;
-        this.queryPrefix = queryPrefix;
+        this.methodPrefix = methodPrefix;
     }
 
-    public static QueryRoot create(String method, RepositoryComponent repo)
+    public static QueryRoot create(String method, RepositoryComponent repo, MethodPrefix prefix)
     {
-        QueryRoot root = new QueryRoot(repo.getEntityName(), repo.getMethodPrefix());
+        QueryRoot root = new QueryRoot(repo.getEntityName(), prefix);
         root.build(method, method, repo);
         root.createJpql();
         return root;
@@ -121,16 +122,12 @@ public class QueryRoot extends QueryPart
 
     private boolean hasQueryConditions(String[] orderByParts)
     {
-        return !queryPrefix.equals(orderByParts[0]);
+        return !methodPrefix.getPrefix().equals(orderByParts[0]);
     }
 
     private String removePrefix(String queryPart)
     {
-        if (queryPart.startsWith(queryPrefix))
-        {
-            return queryPart.substring(queryPrefix.length());
-        }
-        return queryPart;
+        return methodPrefix.removePrefix(queryPart);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/DefaultQueryResult.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/DefaultQueryResult.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/DefaultQueryResult.java
index a0fafb3..557d156 100644
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/DefaultQueryResult.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/DefaultQueryResult.java
@@ -23,6 +23,7 @@ import java.util.List;
 
 import javax.persistence.FlushModeType;
 import javax.persistence.LockModeType;
+import javax.persistence.NoResultException;
 import javax.persistence.Query;
 import javax.persistence.metamodel.SingularAttribute;
 
@@ -186,6 +187,26 @@ public class DefaultQueryResult<T> implements QueryResult<T>
     }
 
     @Override
+    public T getOptionalResult()
+    {
+        try
+        {
+            return getSingleResult();
+        }
+        catch (NoResultException e)
+        {
+            return null;
+        }
+    }
+
+    @Override
+    public T getAnyResult()
+    {
+        List<T> queryResult = getResultList();
+        return queryResult.size() > 0 ? queryResult.get(0) : null;
+    }
+
+    @Override
     public long count()
     {
         CountQueryPostProcessor counter = new CountQueryPostProcessor();

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessor.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessor.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessor.java
index b39b9ee..deb7993 100644
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessor.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessor.java
@@ -20,9 +20,11 @@ package org.apache.deltaspike.data.impl.builder.result;
 
 import javax.persistence.Query;
 
+import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext;
+
 public interface QueryProcessor
 {
 
-    Object executeQuery(Query query);
+    Object executeQuery(Query query, CdiQueryInvocationContext context);
 
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessorFactory.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessorFactory.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessorFactory.java
index 4b14616..022c22a 100644
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessorFactory.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessorFactory.java
@@ -21,10 +21,13 @@ package org.apache.deltaspike.data.impl.builder.result;
 import java.lang.reflect.Method;
 import java.util.List;
 
+import javax.persistence.NoResultException;
 import javax.persistence.Query;
 
 import org.apache.deltaspike.data.api.Modifying;
 import org.apache.deltaspike.data.api.QueryResult;
+import org.apache.deltaspike.data.api.SingleResultType;
+import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext;
 
 public final class QueryProcessorFactory
 {
@@ -74,7 +77,7 @@ public final class QueryProcessorFactory
     private static final class ListQueryProcessor implements QueryProcessor
     {
         @Override
-        public Object executeQuery(Query query)
+        public Object executeQuery(Query query, CdiQueryInvocationContext context)
         {
             return query.getResultList();
         }
@@ -83,7 +86,7 @@ public final class QueryProcessorFactory
     private static final class NoOpQueryProcessor implements QueryProcessor
     {
         @Override
-        public Object executeQuery(Query query)
+        public Object executeQuery(Query query, CdiQueryInvocationContext context)
         {
             return query;
         }
@@ -92,9 +95,26 @@ public final class QueryProcessorFactory
     private static final class SingleResultQueryProcessor implements QueryProcessor
     {
         @Override
-        public Object executeQuery(Query query)
+        public Object executeQuery(Query query, CdiQueryInvocationContext context)
         {
-            return query.getSingleResult();
+            SingleResultType style = context.getSingleResultStyle();
+            switch (style)
+            {
+                case JPA:
+                    return query.getSingleResult();
+                case OPTIONAL:
+                    try
+                    {
+                        return query.getSingleResult();
+                    }
+                    catch (NoResultException e)
+                    {
+                        return null;
+                    }
+                default:
+                    List<Object> queryResult = query.getResultList();
+                    return queryResult.size() > 0 ? queryResult.get(0) : null;
+            }
         }
     }
 
@@ -109,7 +129,7 @@ public final class QueryProcessorFactory
         }
 
         @Override
-        public Object executeQuery(Query query)
+        public Object executeQuery(Query query, CdiQueryInvocationContext context)
         {
             int result = query.executeUpdate();
             if (!returnsVoid)

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/QueryCriteria.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/QueryCriteria.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/QueryCriteria.java
index 63438db..0c054e3 100644
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/QueryCriteria.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/QueryCriteria.java
@@ -27,6 +27,7 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
 import javax.persistence.TypedQuery;
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
@@ -112,6 +113,26 @@ public class QueryCriteria<C, R> implements Criteria<C, R>
     }
 
     @Override
+    public R getOptionalResult()
+    {
+        try
+        {
+            return getSingleResult();
+        }
+        catch (NoResultException e)
+        {
+            return null;
+        }
+    }
+
+    @Override
+    public R getAnyResult()
+    {
+        List<R> queryResult = getResultList();
+        return queryResult.size() > 0 ? queryResult.get(0) : null;
+    }
+
+    @Override
     public TypedQuery<R> createQuery()
     {
         try

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/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 c4dd208..4549cb6 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
@@ -25,6 +25,7 @@ import java.util.List;
 import javax.persistence.EntityManager;
 import javax.persistence.Query;
 
+import org.apache.deltaspike.data.api.SingleResultType;
 import org.apache.deltaspike.data.api.mapping.QueryInOutMapper;
 import org.apache.deltaspike.data.impl.meta.RepositoryMethod;
 import org.apache.deltaspike.data.impl.param.Parameters;
@@ -175,7 +176,7 @@ public class CdiQueryInvocationContext implements QueryInvocationContext
 
     public Object executeQuery(Query jpaQuery)
     {
-        return repoMethod.getQueryProcessor().executeQuery(jpaQuery);
+        return repoMethod.getQueryProcessor().executeQuery(jpaQuery, this);
     }
 
     public Parameters getParams()
@@ -213,4 +214,9 @@ public class CdiQueryInvocationContext implements QueryInvocationContext
         return repoMethod.getQueryInOutMapperInstance(this);
     }
 
+    public SingleResultType getSingleResultStyle()
+    {
+        return repoMethod.getSingleResultStyle();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryHandler.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryHandler.java
index 809a9a8..f743cb8 100755
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryHandler.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryHandler.java
@@ -29,7 +29,9 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
+import javax.persistence.PersistenceException;
 
+import org.apache.deltaspike.data.api.QueryInvocationException;
 import org.apache.deltaspike.data.api.Repository;
 import org.apache.deltaspike.data.impl.builder.QueryBuilder;
 import org.apache.deltaspike.data.impl.builder.QueryBuilderFactory;
@@ -76,9 +78,13 @@ public class QueryHandler implements Serializable, InvocationHandler
             Object result = builder.executeQuery(queryContext);
             return result;
         }
+        catch (PersistenceException e)
+        {
+            throw e;
+        }
         catch (Exception e)
         {
-            log.log(Level.SEVERE, "Query execution error", e);
+            log.log(Level.FINEST, "Query execution error", e);
             if (queryContext != null)
             {
                 throw new QueryInvocationException(e, queryContext);

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/MethodPrefix.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/MethodPrefix.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/MethodPrefix.java
new file mode 100644
index 0000000..81d8ea2
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/MethodPrefix.java
@@ -0,0 +1,145 @@
+/*
+ * 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.deltaspike.data.impl.meta;
+
+import org.apache.deltaspike.data.api.SingleResultType;
+
+public class MethodPrefix
+{
+    public static final String DEFAULT_PREFIX = "findBy";
+    public static final String DEFAULT_OPT_PREFIX = "findOptionalBy";
+    public static final String DEFAULT_ANY_PREFIX = "findAnyBy";
+
+    private final String customPrefix;
+    private final String methodName;
+
+    public MethodPrefix(String customPrefix, String methodName)
+    {
+        this.customPrefix = customPrefix;
+        this.methodName = methodName;
+    }
+
+    public String removePrefix(String queryPart)
+    {
+        if (hasCustomPrefix() && queryPart.startsWith(customPrefix))
+        {
+            return queryPart.substring(customPrefix.length());
+        }
+        KnownQueryPrefix known = KnownQueryPrefix.fromMethodName(queryPart);
+        if (known != null)
+        {
+            return known.removePrefix(queryPart);
+        }
+        return queryPart;
+    }
+
+    public boolean hasCustomPrefix()
+    {
+        return !"".equals(customPrefix);
+    }
+
+    public String getCustomPrefix()
+    {
+        return customPrefix;
+    }
+
+    public String getPrefix()
+    {
+        if (hasCustomPrefix())
+        {
+            return customPrefix;
+        }
+        KnownQueryPrefix prefix = KnownQueryPrefix.fromMethodName(methodName);
+        if (prefix != null)
+        {
+            return prefix.getPrefix();
+        }
+        return "";
+    }
+
+    public SingleResultType getSingleResultStyle()
+    {
+        KnownQueryPrefix prefix = KnownQueryPrefix.fromMethodName(methodName);
+        if (prefix != null)
+        {
+            return prefix.getStyle();
+        }
+        return SingleResultType.JPA;
+    }
+
+    private static enum KnownQueryPrefix
+    {
+        DEFAULT(DEFAULT_PREFIX)
+        {
+            @Override
+            public SingleResultType getStyle()
+            {
+                return SingleResultType.JPA;
+            }
+        },
+        OPTIONAL(DEFAULT_OPT_PREFIX)
+        {
+            @Override
+            public SingleResultType getStyle()
+            {
+                return SingleResultType.OPTIONAL;
+            }
+        },
+        ANY(DEFAULT_ANY_PREFIX)
+        {
+            @Override
+            public SingleResultType getStyle()
+            {
+                return SingleResultType.ANY;
+            }
+        };
+
+        private final String prefix;
+
+        private KnownQueryPrefix(String prefix)
+        {
+            this.prefix = prefix;
+        }
+
+        public String removePrefix(String queryPart)
+        {
+            return queryPart.substring(prefix.length());
+        }
+
+        public String getPrefix()
+        {
+            return prefix;
+        }
+
+        public abstract SingleResultType getStyle();
+
+        public static KnownQueryPrefix fromMethodName(String name)
+        {
+            for (KnownQueryPrefix mapping : values())
+            {
+                if (name.startsWith(mapping.getPrefix()))
+                {
+                    return mapping;
+                }
+            }
+            return null;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponent.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponent.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponent.java
index 2943555..25f9cc4 100644
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponent.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponent.java
@@ -169,11 +169,6 @@ public class RepositoryComponent
         return repoClass;
     }
 
-    public String getMethodPrefix()
-    {
-        return repoClass.getAnnotation(Repository.class).methodPrefix();
-    }
-
     public boolean hasEntityManagerResolver()
     {
         return getEntityManagerResolverClass() != null;
@@ -255,4 +250,9 @@ public class RepositoryComponent
         return null;
     }
 
+    public String getCustomMethodPrefix()
+    {
+        return repoClass.getAnnotation(Repository.class).methodPrefix();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethod.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethod.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethod.java
index ec79d3f..ac90562 100644
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethod.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethod.java
@@ -32,6 +32,7 @@ import org.apache.deltaspike.core.api.provider.BeanManagerProvider;
 import org.apache.deltaspike.core.api.provider.BeanProvider;
 import org.apache.deltaspike.core.api.provider.DependentProvider;
 import org.apache.deltaspike.data.api.Query;
+import org.apache.deltaspike.data.api.SingleResultType;
 import org.apache.deltaspike.data.api.mapping.MappingConfig;
 import org.apache.deltaspike.data.api.mapping.QueryInOutMapper;
 import org.apache.deltaspike.data.impl.builder.MethodExpressionException;
@@ -55,6 +56,7 @@ public class RepositoryMethod
 
     private final Method method;
     private final MethodType methodType;
+    private final MethodPrefix methodPrefix;
     private final RepositoryComponent repo;
     private final QueryRoot queryRoot;
     private final QueryProcessor queryProcessor;
@@ -66,6 +68,7 @@ public class RepositoryMethod
     {
         this.method = method;
         this.repo = repo;
+        this.methodPrefix = new MethodPrefix(repo.getCustomMethodPrefix(), method.getName());
         this.methodType = extractMethodType();
         this.queryRoot = initQueryRoot();
         this.queryProcessor = QueryProcessorFactory.newInstance(method).build();
@@ -115,7 +118,7 @@ public class RepositoryMethod
     {
         if (methodType == MethodType.PARSE)
         {
-            return QueryRoot.create(method.getName(), repo);
+            return QueryRoot.create(method.getName(), repo, methodPrefix);
         }
         return QueryRoot.UNKNOWN_ROOT;
     }
@@ -143,7 +146,7 @@ public class RepositoryMethod
         }
         try
         {
-            QueryRoot.create(method.getName(), repo);
+            QueryRoot.create(method.getName(), repo, methodPrefix);
             return true;
         }
         catch (MethodExpressionException e)
@@ -218,4 +221,13 @@ public class RepositoryMethod
         return mapper != null;
     }
 
+    public SingleResultType getSingleResultStyle()
+    {
+        if (method.isAnnotationPresent(Query.class))
+        {
+            return method.getAnnotation(Query.class).singleResult();
+        }
+        return methodPrefix.getSingleResultStyle();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/QueryResultTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/QueryResultTest.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/QueryResultTest.java
index 90bcc9a..55db66f 100644
--- a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/QueryResultTest.java
+++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/QueryResultTest.java
@@ -21,6 +21,7 @@ package org.apache.deltaspike.data.impl;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -31,6 +32,7 @@ import javax.inject.Inject;
 import javax.persistence.EntityManager;
 import javax.persistence.FlushModeType;
 import javax.persistence.LockModeType;
+import javax.persistence.NonUniqueResultException;
 import javax.persistence.PersistenceContext;
 
 import org.apache.deltaspike.data.api.QueryResult;
@@ -280,6 +282,53 @@ public class QueryResultTest extends TransactionalTestCase
         assertEquals(2L, result);
     }
 
+    @Test
+    public void should_query_optional()
+    {
+        // given
+        final String name = "should_query_optional";
+        builder.createSimple(name);
+
+        // when
+        Simple result1 = repo.queryResultWithNamed(name).getOptionalResult();
+        Simple result2 = repo.queryResultWithNamed("this_does_not_exist").getOptionalResult();
+
+        // then
+        assertNotNull(result1);
+        assertEquals(name, result1.getName());
+        assertNull(result2);
+    }
+
+    @Test(expected = NonUniqueResultException.class)
+    public void should_fail_query_optional_with_nonunique()
+    {
+        // given
+        final String name = "should_fail_query_optional_with_nonunique";
+        builder.createSimple(name);
+        builder.createSimple(name);
+
+        // when
+        repo.queryResultWithNamed(name).getOptionalResult();
+    }
+
+    @Test
+    public void should_query_any()
+    {
+        // given
+        final String name = "should_query_any";
+        builder.createSimple(name);
+        builder.createSimple(name);
+
+        // when
+        Simple result1 = repo.queryResultWithNamed(name).getAnyResult();
+        Simple result2 = repo.queryResultWithNamed("this_does_not_exist").getAnyResult();
+
+        // then
+        assertNotNull(result1);
+        assertEquals(name, result1.getName());
+        assertNull(result2);
+    }
+
     @Before
     public void setup()
     {

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/builder/part/QueryRootTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/builder/part/QueryRootTest.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/builder/part/QueryRootTest.java
index 4279e62..3184669 100644
--- a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/builder/part/QueryRootTest.java
+++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/builder/part/QueryRootTest.java
@@ -21,6 +21,7 @@ package org.apache.deltaspike.data.impl.builder.part;
 import static org.junit.Assert.assertEquals;
 
 import org.apache.deltaspike.data.impl.builder.MethodExpressionException;
+import org.apache.deltaspike.data.impl.meta.MethodPrefix;
 import org.apache.deltaspike.data.impl.meta.RepositoryComponent;
 import org.apache.deltaspike.data.impl.meta.RepositoryEntity;
 import org.apache.deltaspike.data.test.domain.Simple;
@@ -43,7 +44,7 @@ public class QueryRootTest
                         "where e.name = ?1";
 
         // when
-        String result = QueryRoot.create(name, repo).getJpqlQuery().trim();
+        String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim();
 
         // then
         assertEquals(expected, result);
@@ -65,7 +66,7 @@ public class QueryRootTest
                         "order by e.embedded.embedd desc";
 
         // when
-        String result = QueryRoot.create(name, repo).getJpqlQuery().trim();
+        String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim();
 
         // then
         assertEquals(expected, result);
@@ -81,7 +82,7 @@ public class QueryRootTest
                         "order by e.id asc";
 
         // when
-        String result = QueryRoot.create(name, repo).getJpqlQuery().trim();
+        String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim();
 
         // then
         assertEquals(expected, result);
@@ -94,7 +95,7 @@ public class QueryRootTest
         final String name = "findByInvalid";
 
         // when
-        QueryRoot.create(name, repo);
+        QueryRoot.create(name, repo, prefix(name));
     }
 
     @Test(expected = MethodExpressionException.class)
@@ -104,7 +105,7 @@ public class QueryRootTest
         final String name = "findBy";
 
         // when
-        QueryRoot.create(name, repo);
+        QueryRoot.create(name, repo, prefix(name));
     }
 
     @Test(expected = MethodExpressionException.class)
@@ -114,7 +115,7 @@ public class QueryRootTest
         final String name = "findByNameOrderByInvalidDesc";
 
         // when
-        QueryRoot.create(name, repo);
+        QueryRoot.create(name, repo, prefix(name));
     }
 
     @Test
@@ -127,10 +128,15 @@ public class QueryRootTest
                         "where e.name = ?1";
 
         // when
-        String result = QueryRoot.create(name, repoFetchBy).getJpqlQuery().trim();
+        String result = QueryRoot.create(name, repoFetchBy, new MethodPrefix("fetchBy", name)).getJpqlQuery().trim();
 
         // then
         assertEquals(expected, result);
     }
 
+    private MethodPrefix prefix(final String name)
+    {
+        return new MethodPrefix("", name);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/criteria/CriteriaTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/criteria/CriteriaTest.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/criteria/CriteriaTest.java
index 8368c7b..06a4d2d 100644
--- a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/criteria/CriteriaTest.java
+++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/criteria/CriteriaTest.java
@@ -20,8 +20,10 @@ package org.apache.deltaspike.data.impl.criteria;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.List;
 
 import javax.enterprise.inject.Produces;
@@ -289,6 +291,54 @@ public class CriteriaTest extends TransactionalTestCase
         }
     }
 
+    @Test
+    public void should_create_select_criteria_with_optional_result()
+    {
+        // given
+        final String name = "should_create_select_criteria_with_optional_result";
+        createSimple(name, 10);
+
+        // when
+        Simple result1 = repo.queryOptional(name);
+        Simple result2 = repo.queryOptional(name + "_doesnt exist");
+
+        // then
+        assertNotNull(result1);
+        assertEquals(name, result1.getName());
+        assertNull(result2);
+    }
+
+    @Test(expected = InvocationTargetException.class)
+    public void should_fail_with_optional_nonunique_result()
+    {
+        // given
+        final String name = "should_fail_with_optional_nonunique_result";
+        createSimple(name, 10);
+        createSimple(name, 10);
+
+        // when
+        repo.queryOptional(name);
+
+    }
+
+    @Test
+    public void should_create_select_criteria_with_any_result()
+    {
+        // given
+        final String name = "should_create_select_criteria_with_any_result";
+        createSimple(name, 10);
+        createSimple(name, 10);
+
+        // when
+        Simple result1 = repo.queryAny(name);
+        Simple result2 = repo.queryAny(name + "_doesnt exist");
+
+        // then
+        assertNotNull(result1);
+        assertEquals(name, result1.getName());
+        assertNull(result2);
+    }
+
     @Override
     protected EntityManager getEntityManager()
     {

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/QueryHandlerTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/QueryHandlerTest.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/QueryHandlerTest.java
index b1076d0..712eeb5 100644
--- a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/QueryHandlerTest.java
+++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/QueryHandlerTest.java
@@ -21,6 +21,7 @@ package org.apache.deltaspike.data.impl.handler;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.util.List;
@@ -274,6 +275,100 @@ public class QueryHandlerTest extends TransactionalTestCase
         assertEquals(1, count);
     }
 
+    @Test
+    public void should_create_optinal_query_by_name()
+    {
+        // given
+        final String name = "should_create_optinal_query_by_name";
+        builder.createSimple(name);
+
+        // when
+        Simple result1 = repo.findOptionalByName(name);
+        Simple result2 = repo.findOptionalByName(name + "_doesnt_exist");
+
+        // then
+        assertNotNull(result1);
+        assertEquals(name, result1.getName());
+        assertNull(result2);
+    }
+
+    @Test
+    public void should_create_optinal_query_by_annotation()
+    {
+        // given
+        final String name = "should_create_optinal_query_by_annotation";
+        builder.createSimple(name);
+
+        // when
+        Simple result1 = repo.findByNameOptional(name);
+        Simple result2 = repo.findByNameOptional(name + "_doesnt_exist");
+
+        // then
+        assertNotNull(result1);
+        assertEquals(name, result1.getName());
+        assertNull(result2);
+    }
+
+    @Test(expected = QueryInvocationException.class)
+    public void should_fail_optinal_query_by_name_with_nonunique()
+    {
+        // given
+        final String name = "should_fail_optinal_query_by_name_with_nonunique";
+        builder.createSimple(name);
+        builder.createSimple(name);
+
+        // when
+        repo.findOptionalByName(name);
+    }
+
+    @Test(expected = QueryInvocationException.class)
+    public void should_fail_optinal_query_by_annotation_with_nonunique()
+    {
+        // given
+        final String name = "should_fail_optinal_query_by_annotation_with_nonunique";
+        builder.createSimple(name);
+        builder.createSimple(name);
+
+        // when
+        repo.findByNameOptional(name);
+    }
+
+    @Test
+    public void should_create_any_query_by_name()
+    {
+        // given
+        final String name = "should_create_any_query_by_name";
+        builder.createSimple(name);
+        builder.createSimple(name);
+
+        // when
+        Simple result1 = repo.findAnyByName(name);
+        Simple result2 = repo.findAnyByName(name + "_doesnt_exist");
+
+        // then
+        assertNotNull(result1);
+        assertEquals(name, result1.getName());
+        assertNull(result2);
+    }
+
+    @Test
+    public void should_create_any_query_by_annotation()
+    {
+        // given
+        final String name = "should_create_any_query_by_annotation";
+        builder.createSimple(name);
+        builder.createSimple(name);
+
+        // when
+        Simple result1 = repo.findByNameAny(name);
+        Simple result2 = repo.findByNameAny(name + "_doesnt_exist");
+
+        // then
+        assertNotNull(result1);
+        assertEquals(name, result1.getName());
+        assertNull(result2);
+    }
+
     @Before
     public void setup()
     {

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleCriteriaRepository.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleCriteriaRepository.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleCriteriaRepository.java
index 3c5a159..a4cca1c 100644
--- a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleCriteriaRepository.java
+++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleCriteriaRepository.java
@@ -40,6 +40,20 @@ public abstract class SimpleCriteriaRepository extends AbstractEntityRepository<
                 .getResultList();
     }
 
+    public Simple queryOptional(String name)
+    {
+        return criteria()
+                .eq(Simple_.name, name)
+                .getOptionalResult();
+    }
+
+    public Simple queryAny(String name)
+    {
+        return criteria()
+                .eq(Simple_.name, name)
+                .getAnyResult();
+    }
+
     @SuppressWarnings("unchecked")
     public Statistics queryWithSelect(String name)
     {

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepository.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepository.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepository.java
index 21c41cb..f3d1d07 100755
--- a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepository.java
+++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepository.java
@@ -18,10 +18,13 @@
  */
 package org.apache.deltaspike.data.test.service;
 
+import static javax.persistence.LockModeType.PESSIMISTIC_WRITE;
+import static org.apache.deltaspike.data.api.SingleResultType.ANY;
+import static org.apache.deltaspike.data.api.SingleResultType.OPTIONAL;
+
 import java.util.List;
 
 import javax.persistence.EntityManager;
-import javax.persistence.LockModeType;
 
 import org.apache.deltaspike.data.api.AbstractEntityRepository;
 import org.apache.deltaspike.data.api.FirstResult;
@@ -48,11 +51,17 @@ public abstract class SimpleRepository extends AbstractEntityRepository<Simple,
     @Query(named = Simple.BY_NAME_ENABLED, max = 1)
     public abstract List<Simple> findByNamedQueryIndexed(String name, Boolean enabled);
 
+    @Query(named = Simple.BY_NAME_LIKE, singleResult = OPTIONAL)
+    public abstract Simple findByNameOptional(String name);
+
+    @Query(named = Simple.BY_NAME_LIKE, singleResult = ANY)
+    public abstract Simple findByNameAny(String name);
+
     @Query(named = Simple.BY_NAME_ENABLED)
     public abstract List<Simple> findByNamedQueryRestricted(String name, Boolean enabled,
             @MaxResults int max, @FirstResult Integer first);
 
-    @Query(named = Simple.BY_ID, lock = LockModeType.PESSIMISTIC_WRITE)
+    @Query(named = Simple.BY_ID, lock = PESSIMISTIC_WRITE)
     public abstract Simple findByNamedQueryNamed(
             @QueryParam("id") Long id, @QueryParam("enabled") Boolean enabled);
 
@@ -64,6 +73,10 @@ public abstract class SimpleRepository extends AbstractEntityRepository<Simple,
 
     public abstract Simple findByNameAndEnabled(String name, Boolean enabled);
 
+    public abstract Simple findOptionalByName(String name);
+
+    public abstract Simple findAnyByName(String name);
+
     public abstract List<Simple> findByOrderByCounterAscIdDesc();
 
     @Query(value = "SELECT * from SIMPLE_TABLE s WHERE s.name = ?1", isNative = true)

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f3c00d8c/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/util/TestDeployments.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/util/TestDeployments.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/util/TestDeployments.java
index c93ce26..f5ada14 100755
--- a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/util/TestDeployments.java
+++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/util/TestDeployments.java
@@ -29,6 +29,7 @@ import org.apache.deltaspike.data.api.Query;
 import org.apache.deltaspike.data.api.QueryParam;
 import org.apache.deltaspike.data.api.QueryResult;
 import org.apache.deltaspike.data.api.Repository;
+import org.apache.deltaspike.data.api.SingleResultType;
 import org.apache.deltaspike.data.api.audit.CreatedOn;
 import org.apache.deltaspike.data.api.audit.CurrentUser;
 import org.apache.deltaspike.data.api.audit.ModifiedBy;
@@ -121,7 +122,7 @@ public abstract class TestDeployments
                 .addClasses(AbstractEntityRepository.class, Repository.class, EntityRepository.class,
                         FirstResult.class, MaxResults.class, Modifying.class,
                         Query.class, QueryParam.class, QueryResult.class,
-                        EntityManagerConfig.class, EntityManagerResolver.class)
+                        EntityManagerConfig.class, EntityManagerResolver.class, SingleResultType.class)
                 .addClasses(Criteria.class, QuerySelection.class, CriteriaSupport.class)
                 .addClasses(CreatedOn.class, CurrentUser.class, ModifiedBy.class, ModifiedOn.class)
                 .addClasses(MappingConfig.class, QueryInOutMapper.class)