net.sf.jasperreports.engine.query.JRJpaQueryExecuter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jasperreports Show documentation
Show all versions of jasperreports Show documentation
Free Java Reporting Library
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2022 TIBCO Software Inc. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JasperReports is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JasperReports. If not, see .
*/
package net.sf.jasperreports.engine.query;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRDataset;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JRPropertiesUtil;
import net.sf.jasperreports.engine.JRPropertiesUtil.PropertySuffix;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JRValueParameter;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.data.JRJpaDataSource;
import net.sf.jasperreports.engine.util.JRStringUtil;
/**
* EJBQL query executer that uses the Java Persistence API.
*
* To use EJBQL in queries, an javax.persistence.EntityManager
is needed.
* When running or filling reports the em
need to be supplied with the named parameter {@link net.sf.jasperreports.engine.query.JRJpaQueryExecuterFactory#PARAMETER_JPA_ENTITY_MANAGER}.
*
* Example:
*
*
* Map parameters = new HashMap();
* EntityManager em = emf.createEntityManager();
* parameters.put(JRJpaQueryExecuterFactory.PARAMETER_JPA_ENTITY_MANAGER, em);
* JasperRunManager.runReportToPdfFile(fileName, parameters);
*
*
*
* When dealing with large result sets, pagination can be used by setting the {@link net.sf.jasperreports.engine.query.JRJpaQueryExecuterFactory#PROPERTY_JPA_QUERY_PAGE_SIZE} property in the report template.
*
* Example:
*
*
* <property name="net.sf.jasperreports.ejbql.query.page.size" value="100"/>
*
*
*
* Implementation-specific query hints can be set either using report properties in the report template,
* or by supplying the named parameter {@link net.sf.jasperreports.engine.query.JRJpaQueryExecuterFactory#PARAMETER_JPA_QUERY_HINTS_MAP}
* containing a java.util.Map
with named/value query hints.
*
* Example using report property:
*
*
* <property name="net.sf.jasperreports.ejbql.query.hint.fetchSize" value="100"/>
*
*
* The name of the query hint need to be prefixed with {@link net.sf.jasperreports.engine.query.JRJpaQueryExecuterFactory#PROPERTY_JPA_QUERY_HINT_PREFIX net.sf.jasperreports.ejbql.query.hint.}.
* Above example will set a query hint with the name fetchSize
and the String
value 100
.
*
* Example using map:
*
*
* Map hints = new HashMap();
* hints.put("fetchSize", 100);
* hints.put("anyName", anyObject());
* Map parameters = new HashMap();
* EntityManager em = emf.createEntityManager();
* parameters.put(JRJpaQueryExecuterFactory.PARAMETER_JPA_ENTITY_MANAGER, em);
* parameters.put(JRJpaQueryExecuterFactory.PARAMETER_JPA_QUERY_HINTS_MAP, hints);
* JasperRunManager.runReportToPdfFile(fileName, parameters);
*
*
* Note that when using report properties only String
values can be set as query hint.
* When using a query hints map, any Object
can be set as value.
*
* @author Marcel Overdijk ([email protected])
* @see net.sf.jasperreports.engine.query.JRJpaQueryExecuterFactory
*/
public class JRJpaQueryExecuter extends JRAbstractQueryExecuter
{
private static final Log log = LogFactory.getLog(JRJpaQueryExecuter.class);
public static final String CANONICAL_LANGUAGE = "EJBQL";
private final Integer reportMaxCount;
private EntityManager em;
private Query query;
/**
*
*/
public JRJpaQueryExecuter(
JasperReportsContext jasperReportsContext,
JRDataset dataset,
Map parameters
)
{
super(jasperReportsContext, dataset, parameters);
em = (EntityManager)getParameterValue(JRJpaQueryExecuterFactory.PARAMETER_JPA_ENTITY_MANAGER);
reportMaxCount = (Integer)getParameterValue(JRParameter.REPORT_MAX_COUNT);
if (em == null) {
log.warn("The supplied javax.persistence.EntityManager object is null.");
}
parseQuery();
}
@Override
protected String getCanonicalQueryLanguage()
{
return CANONICAL_LANGUAGE;
}
@Override
public JRDataSource createDatasource() throws JRException {
JRDataSource datasource = null;
String queryString = getQueryString();
if (em != null && queryString != null && queryString.trim().length() > 0) {
createQuery(queryString);
datasource = createResultDatasource();
}
return datasource;
}
/**
* Creates the EJBQL query object.
*
* @param queryString the query string
*/
protected synchronized void createQuery(String queryString) {
if (log.isDebugEnabled())
{
log.debug("EJBQL query: " + queryString);
}
query = em.createQuery(queryString);
// Set parameters.
List parameterNames = getCollectedParameterNames();
if (!parameterNames.isEmpty()) {
// Use set to prevent the parameter to be set multiple times.
Set namesSet = new HashSet<>();
for (Iterator iter = parameterNames.iterator(); iter.hasNext();) {
String parameterName = iter.next();
if (namesSet.add(parameterName)) {
JRValueParameter parameter = getValueParameter(parameterName);
String ejbParamName = getEjbqlParameterName(parameterName);
Object paramValue = parameter.getValue();
if (log.isDebugEnabled())
{
log.debug("Parameter " + ejbParamName + ": " + paramValue);
}
query.setParameter(ejbParamName, paramValue);
}
}
}
// Set query hints.
// First, set query hints supplied by the JPA_QUERY_HINTS_MAP parameter.
Map queryHintsMap = (Map)getParameterValue(JRJpaQueryExecuterFactory.PARAMETER_JPA_QUERY_HINTS_MAP);
if (queryHintsMap != null) {
for (Iterator> i = queryHintsMap.entrySet().iterator(); i.hasNext(); ) {
Map.Entry pairs = i.next();
if (log.isDebugEnabled()) {
log.debug("EJBQL query hint [" + pairs.getKey() + "] set.");
}
query.setHint(pairs.getKey(), pairs.getValue());
}
}
// Second, set query hints supplied by report properties which start with JREjbPersistenceQueryExecuterFactory.PROPERTY_JPA_PERSISTENCE_QUERY_HINT_PREFIX
// Example: net.sf.jasperreports.ejbql.query.hint.fetchSize
// This property will result in a query hint set with the name: fetchSize
List properties = JRPropertiesUtil.getProperties(dataset,
JRJpaQueryExecuterFactory.PROPERTY_JPA_QUERY_HINT_PREFIX);
for (Iterator it = properties.iterator(); it.hasNext();) {
PropertySuffix property = it.next();
String queryHint = property.getSuffix();
if (queryHint.length() > 0) {
String value = property.getValue();
if (log.isDebugEnabled()) {
log.debug("EJBQL query hint [" + queryHint + "] set to: " + value);
}
query.setHint(queryHint, value);
}
}
}
/**
* Creates a data source out of the query result.
*
* @return the data source
*/
protected JRDataSource createResultDatasource() {
JRDataSource resDatasource;
try {
int pageSize = getPropertiesUtil().getIntegerProperty(dataset,
JRJpaQueryExecuterFactory.PROPERTY_JPA_QUERY_PAGE_SIZE,
0);
resDatasource = new JRJpaDataSource(this, pageSize);
}
catch (NumberFormatException e) {
throw
new JRRuntimeException(
EXCEPTION_MESSAGE_KEY_NUMERIC_TYPE_REQUIRED,
new Object[]{JRJpaQueryExecuterFactory.PROPERTY_JPA_QUERY_PAGE_SIZE},
e);
}
return resDatasource;
}
@Override
public synchronized void close() {
query = null;
}
@Override
public synchronized boolean cancelQuery() throws JRException {
return false;
}
@Override
protected String getParameterReplacement(String parameterName) {
return ':' + getEjbqlParameterName(parameterName);
}
protected String getEjbqlParameterName(String parameterName) {
return JRStringUtil.getJavaIdentifier(parameterName);
}
/**
* Runs the query by calling javax.persistence.Query.getResultList
.
*
* All the result rows are returned.
*
* @return the result of the query as a list
*/
public List getResultList() {
if (reportMaxCount != null) {
query.setMaxResults(reportMaxCount);
}
return query.getResultList();
}
/**
* Returns a page of the query results by calling javax.persistence.Query.getResultList
.
*
* @param firstIndex the index of the first row to return
* @param resultCount the number of rows to return
* @return result row list
*/
public List getResultList(int firstIndex, int resultCount) {
if (reportMaxCount != null && firstIndex + resultCount > reportMaxCount) {
resultCount = reportMaxCount - firstIndex;
}
query.setFirstResult(firstIndex);
query.setMaxResults(resultCount);
return query.getResultList();
}
}