📄 querytranslatorimpl.java
字号:
//$Id: QueryTranslatorImpl.java 9636 2006-03-16 14:14:48Z max.andersen@jboss.com $
package org.hibernate.hql.classic;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
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.collections.SequencedHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.ScrollableResults;
import org.hibernate.hql.ParameterTranslations;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.JoinSequence;
import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.exception.JDBCExceptionHelper;
import org.hibernate.hql.FilterTranslator;
import org.hibernate.hql.HolderInstantiator;
import org.hibernate.hql.NameGenerator;
import org.hibernate.impl.IteratorImpl;
import org.hibernate.loader.BasicLoader;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.collection.QueryableCollection;
import org.hibernate.persister.entity.Loadable;
import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.sql.ForUpdateFragment;
import org.hibernate.sql.JoinFragment;
import org.hibernate.sql.QuerySelect;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.type.AssociationType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory;
import org.hibernate.util.ArrayHelper;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.StringHelper;
/**
* An instance of <tt>QueryTranslator</tt> translates a Hibernate
* query string to SQL.
*/
public class QueryTranslatorImpl extends BasicLoader
implements FilterTranslator {
private static final String[] NO_RETURN_ALIASES = new String[] {};
private final String queryIdentifier;
private final String queryString;
private final Map typeMap = new SequencedHashMap();
private final Map collections = new SequencedHashMap();
private List returnedTypes = new ArrayList();
private final List fromTypes = new ArrayList();
private final List scalarTypes = new ArrayList();
private final Map namedParameters = new HashMap();
private final Map aliasNames = new HashMap();
private final Map oneToOneOwnerNames = new HashMap();
private final Map uniqueKeyOwnerReferences = new HashMap();
private final Map decoratedPropertyMappings = new HashMap();
private final List scalarSelectTokens = new ArrayList();
private final List whereTokens = new ArrayList();
private final List havingTokens = new ArrayList();
private final Map joins = new SequencedHashMap();
private final List orderByTokens = new ArrayList();
private final List groupByTokens = new ArrayList();
private final Set querySpaces = new HashSet();
private final Set entitiesToFetch = new HashSet();
private final Map pathAliases = new HashMap();
private final Map pathJoins = new HashMap();
private Queryable[] persisters;
private int[] owners;
private EntityType[] ownerAssociationTypes;
private String[] names;
private boolean[] includeInSelect;
private int selectLength;
private Type[] returnTypes;
private Type[] actualReturnTypes;
private String[][] scalarColumnNames;
private Map tokenReplacements;
private int nameCount = 0;
private int parameterCount = 0;
private boolean distinct = false;
private boolean compiled;
private String sqlString;
private Class holderClass;
private Constructor holderConstructor;
private boolean hasScalars;
private boolean shallowQuery;
private QueryTranslatorImpl superQuery;
private QueryableCollection collectionPersister;
private int collectionOwnerColumn = -1;
private String collectionOwnerName;
private String fetchName;
private String[] suffixes;
private Map enabledFilters;
private static final Log log = LogFactory.getLog( QueryTranslatorImpl.class );
/**
* Construct a query translator
*/
public QueryTranslatorImpl(
String queryIdentifier,
String queryString,
Map enabledFilters,
SessionFactoryImplementor factory) {
super( factory );
this.queryIdentifier = queryIdentifier;
this.queryString = queryString;
this.enabledFilters = enabledFilters;
}
/**
* Construct a query translator
*/
public QueryTranslatorImpl(
String queryString,
Map enabledFilters,
SessionFactoryImplementor factory) {
this( queryString, queryString, enabledFilters, factory );
}
/**
* Compile a subquery
*/
void compile(QueryTranslatorImpl superquery)
throws QueryException, MappingException {
this.tokenReplacements = superquery.tokenReplacements;
this.superQuery = superquery;
this.shallowQuery = true;
this.enabledFilters = superquery.getEnabledFilters();
compile();
}
/**
* Compile a "normal" query. This method may be called multiple
* times. Subsequent invocations are no-ops.
*/
public synchronized void compile(Map replacements, boolean scalar)
throws QueryException, MappingException {
if ( !compiled ) {
this.tokenReplacements = replacements;
this.shallowQuery = scalar;
compile();
}
}
/**
* Compile a filter. This method may be called multiple
* times. Subsequent invocations are no-ops.
*/
public synchronized void compile(String collectionRole, Map replacements, boolean scalar)
throws QueryException, MappingException {
if ( !isCompiled() ) {
addFromAssociation( "this", collectionRole );
compile( replacements, scalar );
}
}
/**
* Compile the query (generate the SQL).
*/
private void compile() throws QueryException, MappingException {
log.trace( "compiling query" );
try {
ParserHelper.parse( new PreprocessingParser( tokenReplacements ),
queryString,
ParserHelper.HQL_SEPARATORS,
this );
renderSQL();
}
catch ( QueryException qe ) {
qe.setQueryString( queryString );
throw qe;
}
catch ( MappingException me ) {
throw me;
}
catch ( Exception e ) {
log.debug( "unexpected query compilation problem", e );
e.printStackTrace();
QueryException qe = new QueryException( "Incorrect query syntax", e );
qe.setQueryString( queryString );
throw qe;
}
postInstantiate();
compiled = true;
}
public String getSQLString() {
return sqlString;
}
public List collectSqlStrings() {
return ArrayHelper.toList( new String[] { sqlString } );
}
public String getQueryString() {
return queryString;
}
/**
* Persisters for the return values of a <tt>find()</tt> style query.
*
* @return an array of <tt>EntityPersister</tt>s.
*/
protected Loadable[] getEntityPersisters() {
return persisters;
}
/**
* Types of the return values of an <tt>iterate()</tt> style query.
*
* @return an array of <tt>Type</tt>s.
*/
public Type[] getReturnTypes() {
return actualReturnTypes;
}
public String[] getReturnAliases() {
// return aliases not supported in classic translator!
return NO_RETURN_ALIASES;
}
public String[][] getColumnNames() {
return scalarColumnNames;
}
private static void logQuery(String hql, String sql) {
if ( log.isDebugEnabled() ) {
log.debug( "HQL: " + hql );
log.debug( "SQL: " + sql );
}
}
void setAliasName(String alias, String name) {
aliasNames.put( alias, name );
}
public String getAliasName(String alias) {
String name = ( String ) aliasNames.get( alias );
if ( name == null ) {
if ( superQuery != null ) {
name = superQuery.getAliasName( alias );
}
else {
name = alias;
}
}
return name;
}
String unalias(String path) {
String alias = StringHelper.root( path );
String name = getAliasName( alias );
if ( name != null ) {
return name + path.substring( alias.length() );
}
else {
return path;
}
}
void addEntityToFetch(String name, String oneToOneOwnerName, AssociationType ownerAssociationType) {
addEntityToFetch( name );
if ( oneToOneOwnerName != null ) oneToOneOwnerNames.put( name, oneToOneOwnerName );
if ( ownerAssociationType != null ) uniqueKeyOwnerReferences.put( name, ownerAssociationType );
}
private void addEntityToFetch(String name) {
entitiesToFetch.add( name );
}
private int nextCount() {
return ( superQuery == null ) ? nameCount++ : superQuery.nameCount++;
}
String createNameFor(String type) {
return StringHelper.generateAlias( type, nextCount() );
}
String createNameForCollection(String role) {
return StringHelper.generateAlias( role, nextCount() );
}
private String getType(String name) {
String type = ( String ) typeMap.get( name );
if ( type == null && superQuery != null ) {
type = superQuery.getType( name );
}
return type;
}
private String getRole(String name) {
String role = ( String ) collections.get( name );
if ( role == null && superQuery != null ) {
role = superQuery.getRole( name );
}
return role;
}
boolean isName(String name) {
return aliasNames.containsKey( name ) ||
typeMap.containsKey( name ) ||
collections.containsKey( name ) || (
superQuery != null && superQuery.isName( name )
);
}
PropertyMapping getPropertyMapping(String name) throws QueryException {
PropertyMapping decorator = getDecoratedPropertyMapping( name );
if ( decorator != null ) return decorator;
String type = getType( name );
if ( type == null ) {
String role = getRole( name );
if ( role == null ) {
throw new QueryException( "alias not found: " + name );
}
return getCollectionPersister( role ); //.getElementPropertyMapping();
}
else {
Queryable persister = getEntityPersister( type );
if ( persister == null ) throw new QueryException( "persistent class not found: " + type );
return persister;
}
}
private PropertyMapping getDecoratedPropertyMapping(String name) {
return ( PropertyMapping ) decoratedPropertyMappings.get( name );
}
void decoratePropertyMapping(String name, PropertyMapping mapping) {
decoratedPropertyMappings.put( name, mapping );
}
private Queryable getEntityPersisterForName(String name) throws QueryException {
String type = getType( name );
Queryable persister = getEntityPersister( type );
if ( persister == null ) throw new QueryException( "persistent class not found: " + type );
return persister;
}
Queryable getEntityPersisterUsingImports(String className) {
final String importedClassName = getFactory().getImportedClassName( className );
if ( importedClassName == null ) {
return null;
}
try {
return ( Queryable ) getFactory().getEntityPersister( importedClassName );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -