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)