![JAR search and dependency download from the Maven repository](/logo.png)
net.sf.jasperreports.engine.query.JRHibernateQueryExecuter Maven / Gradle / Ivy
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2019 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.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.type.Type;
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.JRRuntimeException;
import net.sf.jasperreports.engine.JRValueParameter;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.data.JRHibernateIterateDataSource;
import net.sf.jasperreports.engine.data.JRHibernateListDataSource;
import net.sf.jasperreports.engine.data.JRHibernateScrollDataSource;
import net.sf.jasperreports.engine.util.JRStringUtil;
/**
* HQL query executer that uses Hibernate 3.
*
* @author Lucian Chirita ([email protected])
*/
public class JRHibernateQueryExecuter extends JRAbstractQueryExecuter
{
private static final Log log = LogFactory.getLog(JRHibernateQueryExecuter.class);
public static final String EXCEPTION_MESSAGE_KEY_UNKNOWN_QUERY_RUN_TYPE = "query.hibernate.unknown.query.run.type";
public static final String EXCEPTION_MESSAGE_KEY_UNRESOLVED_TYPE_CONSTANT = "query.hibernate.unresolved.type.constant";
public static final String CANONICAL_LANGUAGE = "HQL";
private static final Map,Type> hibernateTypeMap;
static
{
Class> typeConstantsClass;
try
{
typeConstantsClass = Class.forName("org.hibernate.type.StandardBasicTypes", true, Hibernate.class.getClassLoader());
}
catch (ClassNotFoundException e)
{
typeConstantsClass = Hibernate.class;
}
if (log.isDebugEnabled())
{
log.debug("Hibernate type constants class is " + typeConstantsClass);
}
hibernateTypeMap = new HashMap,Type>();
hibernateTypeMap.put(Boolean.class, loadTypeConstant(typeConstantsClass, "BOOLEAN"));
hibernateTypeMap.put(Byte.class, loadTypeConstant(typeConstantsClass, "BYTE"));
hibernateTypeMap.put(Double.class, loadTypeConstant(typeConstantsClass, "DOUBLE"));
hibernateTypeMap.put(Float.class, loadTypeConstant(typeConstantsClass, "FLOAT"));
hibernateTypeMap.put(Integer.class, loadTypeConstant(typeConstantsClass, "INTEGER"));
hibernateTypeMap.put(Long.class, loadTypeConstant(typeConstantsClass, "LONG"));
hibernateTypeMap.put(Short.class, loadTypeConstant(typeConstantsClass, "SHORT"));
hibernateTypeMap.put(java.math.BigDecimal.class, loadTypeConstant(typeConstantsClass, "BIG_DECIMAL"));
hibernateTypeMap.put(java.math.BigInteger.class, loadTypeConstant(typeConstantsClass, "BIG_INTEGER"));
hibernateTypeMap.put(Character.class, loadTypeConstant(typeConstantsClass, "CHARACTER"));
hibernateTypeMap.put(String.class, loadTypeConstant(typeConstantsClass, "STRING"));
hibernateTypeMap.put(java.util.Date.class, loadTypeConstant(typeConstantsClass, "DATE"));
hibernateTypeMap.put(java.sql.Timestamp.class, loadTypeConstant(typeConstantsClass, "TIMESTAMP"));
hibernateTypeMap.put(java.sql.Time.class, loadTypeConstant(typeConstantsClass, "TIME"));
}
private static final Type loadTypeConstant(Class> typeConstantsClass, String name)
{
try
{
Field constant = typeConstantsClass.getField(name);
if (!Modifier.isStatic(constant.getModifiers())
|| !Type.class.isAssignableFrom(constant.getType()))
{
throw
new JRRuntimeException(
EXCEPTION_MESSAGE_KEY_UNRESOLVED_TYPE_CONSTANT,
new Object[]{name, typeConstantsClass.getName()});
}
Type type = (Type) constant.get(null);
return type;
}
catch (NoSuchFieldException e)
{
throw new JRRuntimeException(e);
}
catch (SecurityException e)
{
throw new JRRuntimeException(e);
}
catch (IllegalArgumentException e)
{
throw new JRRuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new JRRuntimeException(e);
}
}
private final Integer reportMaxCount;
private Session session;
private Query query;
private boolean queryRunning;
private ScrollableResults scrollableResults;
private boolean isClearCache;
/**
*
*/
public JRHibernateQueryExecuter(
JasperReportsContext jasperReportsContext,
JRDataset dataset, Map parameters
)
{
super(jasperReportsContext, dataset, parameters);
session = (Session) getParameterValue(JRHibernateQueryExecuterFactory.PARAMETER_HIBERNATE_SESSION);
reportMaxCount = (Integer) getParameterValue(JRParameter.REPORT_MAX_COUNT);
isClearCache = getPropertiesUtil().getBooleanProperty(dataset,
JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_CLEAR_CACHE,
false);
if (session == null)
{
log.warn("The supplied org.hibernate.Session object is null.");
}
parseQuery();
}
@Override
protected String getCanonicalQueryLanguage()
{
return CANONICAL_LANGUAGE;
}
/**
* Creates an instance of {@link JRHibernateListDataSource JRHibernateListDataSource},
* {@link JRHibernateIterateDataSource JRHibernateIterateDataSource} or
* {@link JRHibernateScrollDataSource JRHibernateScrollDataSource}, depending on the
*/
@Override
public JRDataSource createDatasource() throws JRException
{
JRDataSource datasource = null;
String queryString = getQueryString();
if (session != null && queryString != null && queryString.trim().length() > 0)
{
createQuery(queryString);
datasource = createResultDatasource();
}
return datasource;
}
/**
* Creates a data source out of the query result.
*
* @return the data source
*/
protected JRDataSource createResultDatasource()
{
JRDataSource resDatasource;
String runType = getPropertiesUtil().getProperty(dataset,
JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_QUERY_RUN_TYPE);
boolean useFieldDescriptions = getPropertiesUtil().getBooleanProperty(dataset,
JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_FIELD_MAPPING_DESCRIPTIONS,
true);
if (runType == null || runType.equals(JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_LIST))
{
try
{
int pageSize = getPropertiesUtil().getIntegerProperty(dataset,
JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_QUERY_LIST_PAGE_SIZE,
0);
resDatasource = new JRHibernateListDataSource(this, useFieldDescriptions, pageSize);
}
catch (NumberFormatException e)
{
throw
new JRRuntimeException(
EXCEPTION_MESSAGE_KEY_NUMERIC_TYPE_REQUIRED,
new Object[]{JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_QUERY_LIST_PAGE_SIZE},
e);
}
}
else if (runType.equals(JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_ITERATE))
{
resDatasource = new JRHibernateIterateDataSource(this, useFieldDescriptions);
}
else if (runType.equals(JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_SCROLL))
{
resDatasource = new JRHibernateScrollDataSource(this, useFieldDescriptions);
}
else
{
throw
new JRRuntimeException(
EXCEPTION_MESSAGE_KEY_UNKNOWN_QUERY_RUN_TYPE,
new Object[]{
JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_QUERY_RUN_TYPE,
JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_LIST,
JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_ITERATE,
JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_SCROLL});
}
return resDatasource;
}
/**
* Creates the Hibernate query object.
*
* If the value of the {@link JRHibernateQueryExecuterFactory#PARAMETER_HIBERNATE_FILTER_COLLECTION PARAMETER_HIBERNATE_FILTER_COLLECTION}
* is not null, then a filter query is created using the value of the parameter as the collection.
*
* @param queryString the query string
*/
protected synchronized void createQuery(String queryString)
{
if (log.isDebugEnabled())
{
log.debug("HQL query: " + queryString);
}
Object filterCollection = getParameterValue(JRHibernateQueryExecuterFactory.PARAMETER_HIBERNATE_FILTER_COLLECTION);
if (filterCollection == null)
{
query = session.createQuery(queryString);
}
else
{
query = session.createFilter(filterCollection, queryString);
}
query.setReadOnly(true);
int fetchSize = getPropertiesUtil().getIntegerProperty(dataset,
JRJdbcQueryExecuterFactory.PROPERTY_JDBC_FETCH_SIZE,
0);
if (fetchSize != 0)
{
query.setFetchSize(fetchSize);
}
setParameters();
}
/**
* Binds values for all the query parameters.
*/
protected void setParameters()
{
List parameterNames = getCollectedParameterNames();
if (!parameterNames.isEmpty())
{
Set namesSet = new HashSet();
for (Iterator iter = parameterNames.iterator(); iter.hasNext();)
{
String parameterName = iter.next();
if (namesSet.add(parameterName))
{
JRValueParameter parameter = getValueParameter(parameterName);
setParameter(parameter);
}
}
}
}
/**
* Binds a parameter value to a query parameter.
*
* @param parameter the report parameter
*/
protected void setParameter(JRValueParameter parameter)
{
String hqlParamName = getHqlParameterName(parameter.getName());
Class> clazz = parameter.getValueClass();
Object parameterValue = parameter.getValue();
if (log.isDebugEnabled())
{
log.debug("Parameter " + hqlParamName + " of type " + clazz.getName() + ": " + parameterValue);
}
Type type = hibernateTypeMap.get(clazz);
if (type != null)
{
query.setParameter(hqlParamName, parameterValue, type);
}
else if (Collection.class.isAssignableFrom(clazz))
{
query.setParameterList(hqlParamName, (Collection>) parameterValue);
}
else
{
if (session.getSessionFactory().getClassMetadata(clazz) != null) //param type is a hibernate mapped entity
{
query.setEntity(hqlParamName, parameterValue);
}
else //let hibernate try to guess the type
{
query.setParameter(hqlParamName, parameterValue);
}
}
}
/**
* Closes the scrollable result when scroll execution type is used.
*/
@Override
public synchronized void close()
{
closeScrollableResults();
query = null;
}
/**
* Closes the scrollable results of the query.
*/
public void closeScrollableResults()
{
if (scrollableResults != null)
{
try
{
scrollableResults.close();
}
finally
{
scrollableResults = null;
}
}
}
@Override
public synchronized boolean cancelQuery() throws JRException
{
if (queryRunning)
{
session.cancelQuery();
return true;
}
return false;
}
@Override
protected String getParameterReplacement(String parameterName)
{
return ':' + getHqlParameterName(parameterName);
}
protected String getHqlParameterName(String parameterName)
{
return '_' + JRStringUtil.getJavaIdentifier(parameterName);
}
/**
* Returns the return types of the HQL query.
*
* @return the return types of the HQL query
*/
public Type[] getReturnTypes()
{
return query.getReturnTypes();
}
/**
* Returns the aliases of the HQL query.
*
* @return the aliases of the HQL query
*/
public String[] getReturnAliases()
{
return query.getReturnAliases();
}
/**
* Returns the dataset for which the query executer has been created.
*
* @return the dataset for which the query executer has been created
*/
public JRDataset getDataset()
{
return dataset;
}
/**
* Runs the query by calling org.hibernate.Query.list()
.
*
* All the result rows are returned.
*
* @return the result of the query as a list
*/
public List> list()
{
setMaxCount();
setQueryRunning(true);
try
{
return query.list();
}
finally
{
setQueryRunning(false);
}
}
protected synchronized void setQueryRunning(boolean queryRunning)
{
this.queryRunning = queryRunning;
}
private void setMaxCount()
{
if (reportMaxCount != null)
{
query.setMaxResults(reportMaxCount);
}
}
/**
* Returns a page of the query results by calling org.hibernate.Query.iterate()
.
*
* @param firstIndex the index of the first row to return
* @param resultCount the number of rows to return
* @return result row list
*/
public List> list(int firstIndex, int resultCount)
{
if (reportMaxCount != null && firstIndex + resultCount > reportMaxCount)
{
resultCount = reportMaxCount - firstIndex;
}
query.setFirstResult(firstIndex);
query.setMaxResults(resultCount);
if (isClearCache)
{
clearCache();
}
return query.list();
}
/**
* Runs the query by calling org.hibernate.Query.iterate()
.
*
* @return query iterator
*/
public Iterator> iterate()
{
setMaxCount();
setQueryRunning(true);
try
{
return query.iterate();
}
finally
{
setQueryRunning(false);
}
}
/**
* Runs the query by calling org.hibernate.Query.scroll()
.
*
* @return scrollable results of the query
*/
public ScrollableResults scroll()
{
setMaxCount();
setQueryRunning(true);
try
{
scrollableResults = query.scroll(ScrollMode.FORWARD_ONLY);
}
finally
{
setQueryRunning(false);
}
return scrollableResults;
}
public void clearCache()
{
session.flush();
session.clear();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy