/* * Copyright 2007 The Fornax Project Team, including the original * author or authors. * * Licensed 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.sculptor.framework.accessimpl.jpa; import java.util.Map; import javax.persistence.Query; import javax.persistence.TypedQuery; import org.sculptor.framework.domain.Property; /** * <p> * Implementation of Access command FindByQueryAccess. * </p> * <p> * Command design pattern. * </p> */ public abstract class JpaJpqlQueryAccessBase<T,R> extends JpaQueryAccessBase<T,R> { private String query; private Boolean namedQuery; private Property<?>[] fetchEager; private TypedQuery<Long> resultCountQuery = null; public JpaJpqlQueryAccessBase() { super(); } @SuppressWarnings("unchecked") public JpaJpqlQueryAccessBase(Class<T> type) { super(type, (Class<R>) type); } public JpaJpqlQueryAccessBase(Class<T> type, Class<R> resultType) { super(type, resultType); } protected String getQuery() { return query; } public void setQuery(String query) { this.query = query; } public void setFetchEager(Property<?>[] fetchEager) { this.fetchEager = fetchEager; } public Property<?>[] getFetchEager() { return fetchEager; } protected TypedQuery<Long> getResultCountQuery() { return resultCountQuery; } protected void setResultCountQuery(TypedQuery<Long> resultCountQuery) { this.resultCountQuery = resultCountQuery; } protected boolean isNamedQuery() { if (namedQuery != null) { return namedQuery; } if (query == null) { return false; } return !query.trim().contains(" "); } public void setNamedQuery(boolean namedQuery) { this.namedQuery = namedQuery; } @Override protected TypedQuery<R> prepareTypedQuery(QueryConfig config) { if (isNamedQuery()) { return getEntityManager().createNamedQuery(query, getResultType()); } else { return getEntityManager().createQuery(query, getResultType()); } } @Override protected Query prepareUntypedQuery(QueryConfig config) { if (isNamedQuery()) { return getEntityManager().createNamedQuery(query); } else { return getEntityManager().createQuery(query); } } @Override final protected void prepareOrderBy(QueryConfig config) { // if (config.hasOrders()) { if (config.isSingleResult() || isNamedQuery()) { if (config.throwExceptionOnConfigurationError()) { throw new QueryConfigException("Query returns a single result or is a named query, 'order by' not allowed."); } return; } if (query.contains("order by")) { if (config.throwExceptionOnConfigurationError()) { throw new QueryConfigException("Query contains 'order by' already."); } return; } // } prepareOrderBy(query, config); } protected void prepareOrderBy(String query, QueryConfig config) { // query += " order by " + config.getOrderBy(); } @Override protected void prepareHints(Query query, QueryConfig config) { if (!isNamedQuery()) { super.prepareHints(query, config); } } @Override protected void prepareResultCount(QueryConfig config) { if (isNamedQuery()) { // try find a named query for counting rows if (JpaHelper.findNamedQuery(getType(), query.replace("find", "count")) != null) { resultCountQuery = getEntityManager().createNamedQuery(query.replace("find", "count"), Long.class); } else { // guess a query for counting rows based on the named query resultCountQuery = getEntityManager().createQuery( JpaHelper.createResultCountQuery( JpaHelper.findNamedQuery(getType(), query).query()), Long.class); } } else { // guess a query for counting rows based on the query string resultCountQuery = getEntityManager().createQuery( JpaHelper.createResultCountQuery(query), Long.class); } }; @Override public void executeResultCount() { if (resultCountQuery != null) { if (getParameters() != null) { for (Map.Entry<String, ?> entry : getParameters().entrySet()) { resultCountQuery.setParameter(entry.getKey(), entry.getValue()); } } setResultCount(resultCountQuery.getSingleResult()); } } }