From 286800ec3499de449fae8e54e6a3238dcfe85212 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 21 May 2013 17:54:14 -0500 Subject: [PATCH] HHH-8211 - Checkstyle and FindBugs fix-ups --- .../internal/CollectionLoadContext.java | 77 +++++----- .../loading/internal/EntityLoadContext.java | 3 +- .../engine/loading/internal/LoadContexts.java | 34 ++--- .../internal/LoadingCollectionEntry.java | 3 +- .../engine/loading/internal/package-info.java | 28 ++++ .../hibernate/engine/profile/Association.java | 6 + .../org/hibernate/engine/profile/Fetch.java | 22 ++- .../engine/profile/FetchProfile.java | 29 ++-- .../engine/profile/package-info.java | 4 + .../engine/query/spi/FilterQueryPlan.java | 23 ++- .../engine/query/spi/HQLQueryPlan.java | 140 +++++++++++++----- .../query/spi/NamedParameterDescriptor.java | 19 ++- .../engine/query/spi/NativeSQLQueryPlan.java | 70 +++++---- .../query/spi/OrdinalParameterDescriptor.java | 15 +- .../query/spi/ParamLocationRecognizer.java | 12 +- .../engine/query/spi/ParameterMetadata.java | 102 +++++++++++-- .../engine/query/spi/ParameterParser.java | 73 +++++++-- .../engine/query/spi/QueryMetadata.java | 95 ------------ .../engine/query/spi/QueryPlanCache.java | 114 ++++++++++---- .../engine/query/spi/ReturnMetadata.java | 10 +- .../engine/query/spi/package-info.java | 4 + 21 files changed, 571 insertions(+), 312 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/loading/internal/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/profile/package-info.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryMetadata.java create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/query/spi/package-info.java diff --git a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java index e84c637dfa..9fd09535cd 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java @@ -62,7 +62,7 @@ public class CollectionLoadContext { private final LoadContexts loadContexts; private final ResultSet resultSet; - private Set localLoadingCollectionKeys = new HashSet(); + private Set localLoadingCollectionKeys = new HashSet(); /** * Creates a collection load context for the given result set. @@ -119,12 +119,13 @@ public class CollectionLoadContext { if ( collection != null ) { if ( collection.wasInitialized() ) { LOG.trace( "Collection already initialized; ignoring" ); - return null; // ignore this row of results! Note the early exit + // ignore this row of results! Note the early exit + return null; } LOG.trace( "Collection not yet initialized; initializing" ); } else { - Object owner = loadContexts.getPersistenceContext().getCollectionOwner( key, persister ); + final Object owner = loadContexts.getPersistenceContext().getCollectionOwner( key, persister ); final boolean newlySavedEntity = owner != null && loadContexts.getPersistenceContext().getEntry( owner ).getStatus() != Status.LOADING; if ( newlySavedEntity ) { @@ -162,7 +163,7 @@ public class CollectionLoadContext { * @param persister The persister for which to complete loading. */ public void endLoadingCollections(CollectionPersister persister) { - SessionImplementor session = getLoadContext().getPersistenceContext().getSession(); + final SessionImplementor session = getLoadContext().getPersistenceContext().getSession(); if ( !loadContexts.hasLoadingCollectionEntries() && localLoadingCollectionKeys.isEmpty() ) { return; @@ -174,17 +175,17 @@ public class CollectionLoadContext { // internal loadingCollections map for matches and store those matches // in a temp collection. the temp collection is then used to "drive" // the #endRead processing. - List matches = null; - Iterator iter = localLoadingCollectionKeys.iterator(); - while ( iter.hasNext() ) { - final CollectionKey collectionKey = (CollectionKey) iter.next(); + List matches = null; + final Iterator itr = localLoadingCollectionKeys.iterator(); + while ( itr.hasNext() ) { + final CollectionKey collectionKey = (CollectionKey) itr.next(); final LoadingCollectionEntry lce = loadContexts.locateLoadingCollectionEntry( collectionKey ); if ( lce == null ) { LOG.loadingCollectionKeyNotFound( collectionKey ); } else if ( lce.getResultSet() == resultSet && lce.getPersister() == persister ) { if ( matches == null ) { - matches = new ArrayList(); + matches = new ArrayList(); } matches.add( lce ); if ( lce.getCollection().getOwner() == null ) { @@ -201,7 +202,7 @@ public class CollectionLoadContext { // todo : i'd much rather have this done from #endLoadingCollection(CollectionPersister,LoadingCollectionEntry)... loadContexts.unregisterLoadingCollectionXRef( collectionKey ); - iter.remove(); + itr.remove(); } } @@ -217,29 +218,35 @@ public class CollectionLoadContext { } } - private void endLoadingCollections(CollectionPersister persister, List matchedCollectionEntries) { + private void endLoadingCollections(CollectionPersister persister, List matchedCollectionEntries) { final boolean debugEnabled = LOG.isDebugEnabled(); if ( matchedCollectionEntries == null ) { - if ( debugEnabled ) LOG.debugf( "No collections were found in result set for role: %s", persister.getRole() ); + if ( debugEnabled ) { + LOG.debugf( "No collections were found in result set for role: %s", persister.getRole() ); + } return; } final int count = matchedCollectionEntries.size(); - if ( debugEnabled ) LOG.debugf("%s collections were found in result set for role: %s", count, persister.getRole()); - - for ( int i = 0; i < count; i++ ) { - LoadingCollectionEntry lce = ( LoadingCollectionEntry ) matchedCollectionEntries.get( i ); - endLoadingCollection( lce, persister ); + if ( debugEnabled ) { + LOG.debugf( "%s collections were found in result set for role: %s", count, persister.getRole() ); } - if ( debugEnabled ) LOG.debugf( "%s collections initialized for role: %s", count, persister.getRole() ); + for ( LoadingCollectionEntry matchedCollectionEntry : matchedCollectionEntries ) { + endLoadingCollection( matchedCollectionEntry, persister ); + } + + if ( debugEnabled ) { + LOG.debugf( "%s collections initialized for role: %s", count, persister.getRole() ); + } } private void endLoadingCollection(LoadingCollectionEntry lce, CollectionPersister persister) { LOG.tracev( "Ending loading collection [{0}]", lce ); final SessionImplementor session = getLoadContext().getPersistenceContext().getSession(); - boolean hasNoQueuedAdds = lce.getCollection().endRead(); // warning: can cause a recursive calls! (proxy initialization) + // warning: can cause a recursive calls! (proxy initialization) + final boolean hasNoQueuedAdds = lce.getCollection().endRead(); if ( persister.getCollectionType().hasHolder() ) { getLoadContext().getPersistenceContext().addCollectionHolder( lce.getCollection() ); @@ -255,13 +262,16 @@ public class CollectionLoadContext { // getLoadContext().getPersistenceContext().getBatchFetchQueue().removeBatchLoadableCollection(ce); // } } - - boolean addToCache = hasNoQueuedAdds && // there were no queued additions - persister.hasCache() && // and the role has a cache - session.getCacheMode().isPutEnabled() && - !ce.isDoremove(); // and this is not a forced initialization during flush + // add to cache if: + boolean addToCache = + // there were no queued additions + hasNoQueuedAdds + // and the role has a cache + && persister.hasCache() + // and this is not a forced initialization during flush + && session.getCacheMode().isPutEnabled() && !ce.isDoremove(); if ( addToCache ) { addCollectionToCache( lce, persister ); } @@ -269,11 +279,11 @@ public class CollectionLoadContext { if ( LOG.isDebugEnabled() ) { LOG.debugf( "Collection fully initialized: %s", - MessageHelper.collectionInfoString(persister, lce.getCollection(), lce.getKey(), session) + MessageHelper.collectionInfoString( persister, lce.getCollection(), lce.getKey(), session ) ); } if ( session.getFactory().getStatistics().isStatisticsEnabled() ) { - session.getFactory().getStatisticsImplementor().loadCollection(persister.getRole()); + session.getFactory().getStatisticsImplementor().loadCollection( persister.getRole() ); } } @@ -302,7 +312,8 @@ public class CollectionLoadContext { // currently this works in conjuction with the check on // DefaultInitializeCollectionEventHandler.initializeCollectionFromCache() (which makes sure to not read from // cache with enabled filters). - return; // EARLY EXIT!!!!! + // EARLY EXIT!!!!! + return; } final Object version; @@ -315,7 +326,7 @@ public class CollectionLoadContext { // about its owner, that owner should be the same instance as associated with the PC, but we do the // resolution against the PC anyway just to be safe since the lookup should not be costly. if ( lce.getCollection() != null ) { - Object linkedOwner = lce.getCollection().getOwner(); + final Object linkedOwner = lce.getCollection().getOwner(); if ( linkedOwner != null ) { final Serializable ownerKey = persister.getOwnerEntityPersister().getIdentifier( linkedOwner, session ); collectionOwner = getLoadContext().getPersistenceContext().getCollectionOwner( ownerKey, persister ); @@ -335,11 +346,11 @@ public class CollectionLoadContext { version = null; } - CollectionCacheEntry entry = new CollectionCacheEntry( lce.getCollection(), persister ); - CacheKey cacheKey = session.generateCacheKey( lce.getKey(), persister.getKeyType(), persister.getRole() ); - boolean put = persister.getCacheAccessStrategy().putFromLoad( + final CollectionCacheEntry entry = new CollectionCacheEntry( lce.getCollection(), persister ); + final CacheKey cacheKey = session.generateCacheKey( lce.getKey(), persister.getKeyType(), persister.getRole() ); + final boolean put = persister.getCacheAccessStrategy().putFromLoad( cacheKey, - persister.getCacheEntryStructure().structure(entry), + persister.getCacheEntryStructure().structure( entry ), session.getTimestamp(), version, factory.getSettings().isMinimalPutsEnabled() && session.getCacheMode()!= CacheMode.REFRESH @@ -360,7 +371,7 @@ public class CollectionLoadContext { @Override - public String toString() { + public String toString() { return super.toString() + ""; } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/EntityLoadContext.java b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/EntityLoadContext.java index e84abeabf5..f706fe757f 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/EntityLoadContext.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/EntityLoadContext.java @@ -41,7 +41,8 @@ public class EntityLoadContext { private final LoadContexts loadContexts; private final ResultSet resultSet; - private final List hydratingEntities = new ArrayList( 20 ); // todo : need map? the prob is a proper key, right? + // todo : need map? the prob is a proper key, right? + private final List hydratingEntities = new ArrayList( 20 ); public EntityLoadContext(LoadContexts loadContexts, ResultSet resultSet) { this.loadContexts = loadContexts; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/LoadContexts.java b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/LoadContexts.java index 5a6e4a6cf2..3b556e12d3 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/LoadContexts.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/LoadContexts.java @@ -30,24 +30,18 @@ import java.util.IdentityHashMap; import java.util.Map; import java.util.Set; -import org.jboss.logging.Logger; - import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.CollectionKey; import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; -import org.hibernate.internal.util.collections.IdentityMap; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.pretty.MessageHelper; /** * Maps {@link ResultSet result-sets} to specific contextual data related to processing that result set *

- * Implementation note: internally an {@link IdentityMap} is used to maintain the mappings mainly because I'd - * rather not be dependent upon potentially bad {@link Object#equals} and {@link Object#hashCode} implementations on - * the JDBC result sets - *

* Considering the JDBC-redesign work, would further like this contextual info not mapped separately, but available * based on the result set being processed. This would also allow maintaining a single mapping as we could reliably * get notification of the result-set closing... @@ -55,8 +49,7 @@ import org.hibernate.pretty.MessageHelper; * @author Steve Ebersole */ public class LoadContexts { - - private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, LoadContexts.class.getName()); + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( LoadContexts.class ); private final PersistenceContext persistenceContext; private Map collectionLoadContexts; @@ -101,11 +94,11 @@ public class LoadContexts { */ public void cleanup(ResultSet resultSet) { if ( collectionLoadContexts != null ) { - CollectionLoadContext collectionLoadContext = collectionLoadContexts.remove( resultSet ); + final CollectionLoadContext collectionLoadContext = collectionLoadContexts.remove( resultSet ); collectionLoadContext.cleanup(); } if ( entityLoadContexts != null ) { - EntityLoadContext entityLoadContext = entityLoadContexts.remove( resultSet ); + final EntityLoadContext entityLoadContext = entityLoadContexts.remove( resultSet ); entityLoadContext.cleanup(); } } @@ -191,7 +184,7 @@ public class LoadContexts { * @return The loading collection, or null if not found. */ public PersistentCollection locateLoadingCollection(CollectionPersister persister, Serializable ownerKey) { - LoadingCollectionEntry lce = locateLoadingCollectionEntry( new CollectionKey( persister, ownerKey ) ); + final LoadingCollectionEntry lce = locateLoadingCollectionEntry( new CollectionKey( persister, ownerKey ) ); if ( lce != null ) { if ( LOG.isTraceEnabled() ) { LOG.tracef( @@ -246,13 +239,13 @@ public class LoadContexts { if ( !hasRegisteredLoadingCollectionEntries() ) { return; } - xrefLoadingCollectionEntries.remove(key); - } + xrefLoadingCollectionEntries.remove( key ); + } @SuppressWarnings( {"UnusedDeclaration"}) Map getLoadingCollectionXRefs() { - return xrefLoadingCollectionEntries; - } + return xrefLoadingCollectionEntries; + } /** @@ -271,7 +264,7 @@ public class LoadContexts { return null; } LOG.tracev( "Attempting to locate loading collection entry [{0}] in any result-set context", key ); - LoadingCollectionEntry rtn = xrefLoadingCollectionEntries.get( key ); + final LoadingCollectionEntry rtn = xrefLoadingCollectionEntries.get( key ); if ( rtn == null ) { LOG.tracev( "Collection [{0}] not located in load context", key ); } @@ -291,6 +284,13 @@ public class LoadContexts { // Entity load contexts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // * currently, not yet used... + /** + * Currently unused + * + * @param resultSet The result set + * + * @return The entity load context + */ @SuppressWarnings( {"UnusedDeclaration"}) public EntityLoadContext getEntityLoadContext(ResultSet resultSet) { EntityLoadContext context = null; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/LoadingCollectionEntry.java b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/LoadingCollectionEntry.java index 27832a7f3f..b25a2d53c9 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/LoadingCollectionEntry.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/LoadingCollectionEntry.java @@ -41,7 +41,7 @@ public class LoadingCollectionEntry { private final Serializable key; private final PersistentCollection collection; - public LoadingCollectionEntry( + LoadingCollectionEntry( ResultSet resultSet, CollectionPersister persister, Serializable key, @@ -68,6 +68,7 @@ public class LoadingCollectionEntry { return collection; } + @Override public String toString() { return getClass().getName() + "@" + Integer.toHexString( hashCode() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/package-info.java b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/package-info.java new file mode 100644 index 0000000000..efcc552137 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/package-info.java @@ -0,0 +1,28 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program 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 this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ + +/** + * Internal classes used to track loading of data, potentially across multiple ResultSets + */ +package org.hibernate.engine.loading.internal; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/profile/Association.java b/hibernate-core/src/main/java/org/hibernate/engine/profile/Association.java index e0b80e891d..dc06efac3d 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/profile/Association.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/profile/Association.java @@ -34,6 +34,12 @@ public class Association { private final String associationPath; private final String role; + /** + * Constructs a association defining what is to be fetched. + * + * @param owner The entity owning the association + * @param associationPath The path of the association, from the entity + */ public Association(EntityPersister owner, String associationPath) { this.owner = owner; this.associationPath = associationPath; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/profile/Fetch.java b/hibernate-core/src/main/java/org/hibernate/engine/profile/Fetch.java index cca676c3e8..431b1878a1 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/profile/Fetch.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/profile/Fetch.java @@ -23,7 +23,6 @@ */ package org.hibernate.engine.profile; - /** * Models an individual fetch within a profile. * @@ -33,6 +32,12 @@ public class Fetch { private final Association association; private final Style style; + /** + * Constructs a Fetch + * + * @param association The association to be fetched + * @param style How to fetch it + */ public Fetch(Association association, Style style) { this.association = association; this.style = style; @@ -54,7 +59,13 @@ public class Fetch { * needed for other things as well anyway). */ public enum Style { + /** + * Fetch via a join + */ JOIN( "join" ), + /** + * Fetch via a subsequent select + */ SELECT( "select" ); private final String name; @@ -63,10 +74,18 @@ public class Fetch { this.name = name; } + @Override public String toString() { return name; } + /** + * Parses a style given an externalized string representation + * + * @param name The externalized representation + * + * @return The style; {@link #JOIN} is returned if not recognized + */ public static Style parse(String name) { if ( SELECT.name.equals( name ) ) { return SELECT; @@ -78,6 +97,7 @@ public class Fetch { } } + @Override public String toString() { return "Fetch[" + style + "{" + association.getRole() + "}]"; } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java b/hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java index e69cc721bf..7acc915246 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java @@ -22,12 +22,11 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.engine.profile; + import java.util.HashMap; import java.util.Map; -import org.jboss.logging.Logger; - -import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.type.BagType; import org.hibernate.type.Type; @@ -41,21 +40,17 @@ import org.hibernate.type.Type; * @author Steve Ebersole */ public class FetchProfile { - - private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, FetchProfile.class.getName()); + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( FetchProfile.class ); private final String name; private Map fetches = new HashMap(); - private boolean containsJoinFetchedCollection = false; - private boolean containsJoinFetchedBag = false; + private boolean containsJoinFetchedCollection; + private boolean containsJoinFetchedBag; private Fetch bagJoinFetch; /** - * A 'fetch profile' is uniquely named within a - * {@link SessionFactoryImplementor SessionFactory}, thus it is also - * uniquely and easily identifiable within that - * {@link SessionFactoryImplementor SessionFactory}. + * Constructs a FetchProfile, supplying its unique name (unique within the SessionFactory). * * @param name The name under which we are bound in the sessionFactory */ @@ -91,7 +86,7 @@ public class FetchProfile { */ public void addFetch(final Fetch fetch) { final String fetchAssociactionRole = fetch.getAssociation().getRole(); - Type associationType = fetch.getAssociation().getOwner().getPropertyType( fetch.getAssociation().getAssociationPath() ); + final Type associationType = fetch.getAssociation().getOwner().getPropertyType( fetch.getAssociation().getAssociationPath() ); if ( associationType.isCollectionType() ) { LOG.tracev( "Handling request to add collection fetch [{0}]", fetchAssociactionRole ); @@ -103,7 +98,8 @@ public class FetchProfile { if ( BagType.class.isInstance( associationType ) ) { if ( containsJoinFetchedCollection ) { LOG.containsJoinFetchedCollection( fetchAssociactionRole ); - return; // EARLY EXIT!!! + // EARLY EXIT!!! + return; } } @@ -144,6 +140,13 @@ public class FetchProfile { return fetches; } + /** + * Obtain the fetch associated with the given role. + * + * @param role The role identifying the fetch + * + * @return The fetch, or {@code null} if a matching one was not found + */ public Fetch getFetchByRole(String role) { return fetches.get( role ); } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/profile/package-info.java b/hibernate-core/src/main/java/org/hibernate/engine/profile/package-info.java new file mode 100644 index 0000000000..e9dbece986 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/engine/profile/package-info.java @@ -0,0 +1,4 @@ +/** + * Models the fetch profiles defined by the application + */ +package org.hibernate.engine.profile; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/FilterQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/FilterQueryPlan.java index de32765bdd..84a2a614e6 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/FilterQueryPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/FilterQueryPlan.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,9 +20,9 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.engine.query.spi; + import java.io.Serializable; import java.util.Map; @@ -38,12 +38,21 @@ public class FilterQueryPlan extends HQLQueryPlan implements Serializable { private final String collectionRole; + /** + * Constructs a query plan for an HQL filter + * + * @param hql The HQL fragment + * @param collectionRole The collection role being filtered + * @param shallow Is the query shallow? + * @param enabledFilters All enabled filters from the Session + * @param factory The factory + */ public FilterQueryPlan( String hql, - String collectionRole, - boolean shallow, - Map enabledFilters, - SessionFactoryImplementor factory) { + String collectionRole, + boolean shallow, + Map enabledFilters, + SessionFactoryImplementor factory) { super( hql, collectionRole, shallow, enabledFilters, factory ); this.collectionRole = collectionRole; } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java index 6d229c65c6..404000ea4b 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java @@ -32,8 +32,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.jboss.logging.Logger; - +import org.hibernate.Filter; import org.hibernate.HibernateException; import org.hibernate.QueryException; import org.hibernate.ScrollableResults; @@ -47,6 +46,7 @@ import org.hibernate.hql.spi.FilterTranslator; import org.hibernate.hql.spi.ParameterTranslations; import org.hibernate.hql.spi.QueryTranslator; import org.hibernate.hql.spi.QueryTranslatorFactory; +import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.EmptyIterator; @@ -60,11 +60,10 @@ import org.hibernate.type.Type; * @author Steve Ebersole */ public class HQLQueryPlan implements Serializable { + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( HQLQueryPlan.class ); // TODO : keep separate notions of QT[] here for shallow/non-shallow queries... - private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, HQLQueryPlan.class.getName()); - private final String sourceQuery; private final QueryTranslator[] translators; private final String[] sqlStrings; @@ -73,17 +72,32 @@ public class HQLQueryPlan implements Serializable { private final ReturnMetadata returnMetadata; private final Set querySpaces; - private final Set enabledFilterNames; + private final Set enabledFilterNames; private final boolean shallow; - public HQLQueryPlan(String hql, boolean shallow, Map enabledFilters, SessionFactoryImplementor factory) { + /** + * Constructs a HQLQueryPlan + * + * @param hql The HQL query + * @param shallow Whether the execution is to be shallow or not + * @param enabledFilters The enabled filters (we only keep the names) + * @param factory The factory + */ + public HQLQueryPlan(String hql, boolean shallow, Map enabledFilters, SessionFactoryImplementor factory) { this( hql, null, shallow, enabledFilters, factory ); } - protected HQLQueryPlan(String hql, String collectionRole, boolean shallow, Map enabledFilters, SessionFactoryImplementor factory){ + @SuppressWarnings("unchecked") + protected HQLQueryPlan( + String hql, + String collectionRole, + boolean shallow, + Map enabledFilters, + SessionFactoryImplementor factory) { this.sourceQuery = hql; this.shallow = shallow; - Set copy = new HashSet(); + + final Set copy = new HashSet(); copy.addAll( enabledFilters.keySet() ); this.enabledFilterNames = java.util.Collections.unmodifiableSet( copy ); @@ -91,8 +105,8 @@ public class HQLQueryPlan implements Serializable { final int length = concreteQueryStrings.length; this.translators = new QueryTranslator[length]; - List sqlStringList = new ArrayList(); - Set combinedQuerySpaces = new HashSet(); + final List sqlStringList = new ArrayList(); + final Set combinedQuerySpaces = new HashSet(); final boolean hasCollectionRole = (collectionRole == null); final Map querySubstitutions = factory.getSettings().getQuerySubstitutions(); @@ -107,7 +121,7 @@ public class HQLQueryPlan implements Serializable { else { translators[i] = queryTranslatorFactory .createFilterTranslator( hql, concreteQueryStrings[i], enabledFilters, factory ); - ( ( FilterTranslator ) translators[i] ).compile( collectionRole, querySubstitutions, shallow ); + ( (FilterTranslator) translators[i] ).compile( collectionRole, querySubstitutions, shallow ); } combinedQuerySpaces.addAll( translators[i].getQuerySpaces() ); sqlStringList.addAll( translators[i].collectSqlStrings() ); @@ -165,20 +179,33 @@ public class HQLQueryPlan implements Serializable { return shallow; } + /** + * Coordinates the efforts to perform a list across all the included query translators. + * + * @param queryParameters The query parameters + * @param session The session + * + * @return The query result list + * + * @throws HibernateException Indicates a problem performing the query + */ + @SuppressWarnings("unchecked") public List performList( QueryParameters queryParameters, - SessionImplementor session) throws HibernateException { + SessionImplementor session) throws HibernateException { if ( LOG.isTraceEnabled() ) { LOG.tracev( "Find: {0}", getSourceQuery() ); queryParameters.traceParameters( session.getFactory() ); } - boolean hasLimit = queryParameters.getRowSelection() != null && - queryParameters.getRowSelection().definesLimits(); - boolean needsLimit = hasLimit && translators.length > 1; - QueryParameters queryParametersToUse; + + final boolean hasLimit = queryParameters.getRowSelection() != null + && queryParameters.getRowSelection().definesLimits(); + final boolean needsLimit = hasLimit && translators.length > 1; + + final QueryParameters queryParametersToUse; if ( needsLimit ) { LOG.needsLimit(); - RowSelection selection = new RowSelection(); + final RowSelection selection = new RowSelection(); selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() ); selection.setTimeout( queryParameters.getRowSelection().getTimeout() ); queryParametersToUse = queryParameters.createCopyUsing( selection ); @@ -187,12 +214,12 @@ public class HQLQueryPlan implements Serializable { queryParametersToUse = queryParameters; } - List combinedResults = new ArrayList(); - IdentitySet distinction = new IdentitySet(); + final List combinedResults = new ArrayList(); + final IdentitySet distinction = new IdentitySet(); int includedCount = -1; translator_loop: for ( QueryTranslator translator : translators ) { - List tmp = translator.list( session, queryParametersToUse ); + final List tmp = translator.list( session, queryParametersToUse ); if ( needsLimit ) { // NOTE : firstRow is zero-based final int first = queryParameters.getRowSelection().getFirstRow() == null @@ -223,9 +250,20 @@ public class HQLQueryPlan implements Serializable { return combinedResults; } + /** + * Coordinates the efforts to perform an iterate across all the included query translators. + * + * @param queryParameters The query parameters + * @param session The session + * + * @return The query result iterator + * + * @throws HibernateException Indicates a problem performing the query + */ + @SuppressWarnings("unchecked") public Iterator performIterate( QueryParameters queryParameters, - EventSource session) throws HibernateException { + EventSource session) throws HibernateException { if ( LOG.isTraceEnabled() ) { LOG.tracev( "Iterate: {0}", getSourceQuery() ); queryParameters.traceParameters( session.getFactory() ); @@ -234,8 +272,8 @@ public class HQLQueryPlan implements Serializable { return EmptyIterator.INSTANCE; } + final boolean many = translators.length > 1; Iterator[] results = null; - boolean many = translators.length > 1; if ( many ) { results = new Iterator[translators.length]; } @@ -248,12 +286,22 @@ public class HQLQueryPlan implements Serializable { } } - return many ? new JoinedIterator(results) : result; + return many ? new JoinedIterator( results ) : result; } + /** + * Coordinates the efforts to perform a scroll across all the included query translators. + * + * @param queryParameters The query parameters + * @param session The session + * + * @return The query result iterator + * + * @throws HibernateException Indicates a problem performing the query + */ public ScrollableResults performScroll( QueryParameters queryParameters, - SessionImplementor session) throws HibernateException { + SessionImplementor session) throws HibernateException { if ( LOG.isTraceEnabled() ) { LOG.tracev( "Iterate: {0}", getSourceQuery() ); queryParameters.traceParameters( session.getFactory() ); @@ -268,6 +316,16 @@ public class HQLQueryPlan implements Serializable { return translators[0].scroll( queryParameters, session ); } + /** + * Coordinates the efforts to perform an execution across all the included query translators. + * + * @param queryParameters The query parameters + * @param session The session + * + * @return The aggregated "affected row" count + * + * @throws HibernateException Indicates a problem performing the execution + */ public int performExecuteUpdate(QueryParameters queryParameters, SessionImplementor session) throws HibernateException { if ( LOG.isTraceEnabled() ) { @@ -285,32 +343,34 @@ public class HQLQueryPlan implements Serializable { } private ParameterMetadata buildParameterMetadata(ParameterTranslations parameterTranslations, String hql) { - long start = System.currentTimeMillis(); - ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( hql ); - long end = System.currentTimeMillis(); + final long start = System.currentTimeMillis(); + final ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( hql ); + final long end = System.currentTimeMillis(); + if ( LOG.isTraceEnabled() ) { LOG.tracev( "HQL param location recognition took {0} mills ({1})", ( end - start ), hql ); } int ordinalParamCount = parameterTranslations.getOrdinalParameterCount(); - int[] locations = ArrayHelper.toIntArray( recognizer.getOrdinalParameterLocationList() ); + final int[] locations = ArrayHelper.toIntArray( recognizer.getOrdinalParameterLocationList() ); if ( parameterTranslations.supportsOrdinalParameterMetadata() && locations.length != ordinalParamCount ) { throw new HibernateException( "ordinal parameter mismatch" ); } ordinalParamCount = locations.length; - OrdinalParameterDescriptor[] ordinalParamDescriptors = new OrdinalParameterDescriptor[ordinalParamCount]; + + final OrdinalParameterDescriptor[] ordinalParamDescriptors = new OrdinalParameterDescriptor[ordinalParamCount]; for ( int i = 1; i <= ordinalParamCount; i++ ) { ordinalParamDescriptors[ i - 1 ] = new OrdinalParameterDescriptor( i, - parameterTranslations.supportsOrdinalParameterMetadata() - ? parameterTranslations.getOrdinalParameterExpectedType( i ) - : null, - locations[ i - 1 ] + parameterTranslations.supportsOrdinalParameterMetadata() + ? parameterTranslations.getOrdinalParameterExpectedType( i ) + : null, + locations[ i - 1 ] ); } - Map namedParamDescriptorMap = new HashMap(); - Map map = recognizer.getNamedParameterDescriptionMap(); + final Map namedParamDescriptorMap = new HashMap(); + final Map map = recognizer.getNamedParameterDescriptionMap(); for ( final String name : map.keySet() ) { final ParamLocationRecognizer.NamedParameterDescription description = map.get( name ); namedParamDescriptorMap.put( @@ -325,9 +385,15 @@ public class HQLQueryPlan implements Serializable { } return new ParameterMetadata( ordinalParamDescriptors, namedParamDescriptorMap ); } + + /** + * Access to the underlying translators associated with this query + * + * @return The translators + */ public QueryTranslator[] getTranslators() { - QueryTranslator[] copy = new QueryTranslator[translators.length]; - System.arraycopy(translators, 0, copy, 0, copy.length); + final QueryTranslator[] copy = new QueryTranslator[translators.length]; + System.arraycopy( translators, 0, copy, 0, copy.length ); return copy; } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NamedParameterDescriptor.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NamedParameterDescriptor.java index a2edcc0cdb..05300b7ef7 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NamedParameterDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NamedParameterDescriptor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,9 +20,9 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.engine.query.spi; + import java.io.Serializable; import org.hibernate.type.Type; @@ -38,6 +38,14 @@ public class NamedParameterDescriptor implements Serializable { private final int[] sourceLocations; private final boolean jpaStyle; + /** + * Constructs a NamedParameterDescriptor + * + * @param name The name of the parameter + * @param expectedType The expected type of the parameter, according to the translator + * @param sourceLocations The locations of the named parameters (aye aye aye) + * @param jpaStyle Was the parameter a JPA style "named parameter"? + */ public NamedParameterDescriptor(String name, Type expectedType, int[] sourceLocations, boolean jpaStyle) { this.name = name; this.expectedType = expectedType; @@ -61,6 +69,11 @@ public class NamedParameterDescriptor implements Serializable { return jpaStyle; } + /** + * Set the parameters expected type + * + * @param type The new expected type + */ public void resetExpectedType(Type type) { this.expectedType = type; } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NativeSQLQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NativeSQLQueryPlan.java index 84867ca1f4..ae13e45808 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NativeSQLQueryPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NativeSQLQueryPlan.java @@ -30,8 +30,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import org.jboss.logging.Logger; - import org.hibernate.HibernateException; import org.hibernate.QueryException; import org.hibernate.action.internal.BulkOperationCleanupAction; @@ -41,6 +39,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.TypedValue; import org.hibernate.event.spi.EventSource; +import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.loader.custom.sql.SQLCustomQuery; @@ -52,10 +51,7 @@ import org.hibernate.type.Type; * @author Steve Ebersole */ public class NativeSQLQueryPlan implements Serializable { - private static final CoreMessageLogger LOG = Logger.getMessageLogger( - CoreMessageLogger.class, - NativeSQLQueryPlan.class.getName() - ); + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( NativeSQLQueryPlan.class ); private final String sourceQuery; private final SQLCustomQuery customQuery; @@ -87,7 +83,7 @@ public class NativeSQLQueryPlan implements Serializable { } private int[] getNamedParameterLocs(String name) throws QueryException { - Object loc = customQuery.getNamedParameterBindPoints().get( name ); + final Object loc = customQuery.getNamedParameterBindPoints().get( name ); if ( loc == null ) { throw new QueryException( "Named parameter does not appear in Query: " + name, @@ -154,60 +150,73 @@ public class NativeSQLQueryPlan implements Serializable { final SessionImplementor session) throws SQLException { if ( namedParams != null ) { // assumes that types are all of span 1 - Iterator iter = namedParams.entrySet().iterator(); + final Iterator iter = namedParams.entrySet().iterator(); int result = 0; while ( iter.hasNext() ) { - Map.Entry e = (Map.Entry) iter.next(); - String name = (String) e.getKey(); - TypedValue typedval = (TypedValue) e.getValue(); - int[] locs = getNamedParameterLocs( name ); - for (int i = 0; i < locs.length; i++) { - LOG.debugf("bindNamedParameters() %s -> %s [%s]", typedval.getValue(), name, locs[i] + start); - typedval.getType().nullSafeSet( ps, typedval.getValue(), - locs[i] + start, session ); + final Map.Entry e = (Map.Entry) iter.next(); + final String name = (String) e.getKey(); + final TypedValue typedval = (TypedValue) e.getValue(); + final int[] locs = getNamedParameterLocs( name ); + for ( int loc : locs ) { + LOG.debugf( "bindNamedParameters() %s -> %s [%s]", typedval.getValue(), name, loc + start ); + typedval.getType().nullSafeSet( + ps, + typedval.getValue(), + loc + start, + session + ); } result += locs.length; } return result; } - return 0; + + return 0; } protected void coordinateSharedCacheCleanup(SessionImplementor session) { - BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, getCustomQuery().getQuerySpaces() ); + final BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, getCustomQuery().getQuerySpaces() ); if ( session.isEventSource() ) { - ( ( EventSource ) session ).getActionQueue().addAction( action ); + ( (EventSource) session ).getActionQueue().addAction( action ); } else { action.getAfterTransactionCompletionProcess().doAfterTransactionCompletion( true, session ); } } - public int performExecuteUpdate(QueryParameters queryParameters, + /** + * Performs the execute query + * + * @param queryParameters The query parameters + * @param session The session + * + * @return The number of affected rows as returned by the JDBC driver + * + * @throws HibernateException Indicates a problem performing the query execution + */ + public int performExecuteUpdate( + QueryParameters queryParameters, SessionImplementor session) throws HibernateException { coordinateSharedCacheCleanup( session ); - if(queryParameters.isCallable()) { + if ( queryParameters.isCallable() ) { throw new IllegalArgumentException("callable not yet supported for native queries"); } int result = 0; PreparedStatement ps; try { - queryParameters.processFilters( this.customQuery.getSQL(), - session ); - String sql = queryParameters.getFilteredSQL(); + queryParameters.processFilters( this.customQuery.getSQL(), session ); + final String sql = queryParameters.getFilteredSQL(); ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false ); try { int col = 1; - col += bindPositionalParameters( ps, queryParameters, col, - session ); - col += bindNamedParameters( ps, queryParameters - .getNamedParameters(), col, session ); + col += bindPositionalParameters( ps, queryParameters, col, session ); + col += bindNamedParameters( ps, queryParameters.getNamedParameters(), col, session ); result = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( ps ); } finally { @@ -218,7 +227,10 @@ public class NativeSQLQueryPlan implements Serializable { } catch (SQLException sqle) { throw session.getFactory().getSQLExceptionHelper().convert( - sqle, "could not execute native bulk manipulation query", this.sourceQuery ); + sqle, + "could not execute native bulk manipulation query", + this.sourceQuery + ); } return result; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/OrdinalParameterDescriptor.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/OrdinalParameterDescriptor.java index ee2d5c6415..deb3ddaf8d 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/OrdinalParameterDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/OrdinalParameterDescriptor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,14 +20,16 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.engine.query.spi; + import java.io.Serializable; import org.hibernate.type.Type; /** + * Descriptor regarding an ordinal parameter. + * * @author Steve Ebersole */ public class OrdinalParameterDescriptor implements Serializable { @@ -35,6 +37,13 @@ public class OrdinalParameterDescriptor implements Serializable { private final Type expectedType; private final int sourceLocation; + /** + * Constructs an ordinal parameter descriptor. + * + * @param ordinalPosition The ordinal position + * @param expectedType The expected type of the parameter + * @param sourceLocation The location of the parameter + */ public OrdinalParameterDescriptor(int ordinalPosition, Type expectedType, int sourceLocation) { this.ordinalPosition = ordinalPosition; this.expectedType = expectedType; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParamLocationRecognizer.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParamLocationRecognizer.java index 8daab1a104..b534668f65 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParamLocationRecognizer.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParamLocationRecognizer.java @@ -38,12 +38,14 @@ import org.hibernate.internal.util.collections.ArrayHelper; * @author Steve Ebersole */ public class ParamLocationRecognizer implements ParameterParser.Recognizer { - + /** + * Internal representation of a recognized named parameter + */ public static class NamedParameterDescription { private final boolean jpaStyle; private final List positions = new ArrayList(); - public NamedParameterDescription(boolean jpaStyle) { + NamedParameterDescription(boolean jpaStyle) { this.jpaStyle = jpaStyle; } @@ -71,7 +73,7 @@ public class ParamLocationRecognizer implements ParameterParser.Recognizer { * @return The generated recognizer, with journaled location info. */ public static ParamLocationRecognizer parseLocations(String query) { - ParamLocationRecognizer recognizer = new ParamLocationRecognizer(); + final ParamLocationRecognizer recognizer = new ParamLocationRecognizer(); ParameterParser.parse( query, recognizer ); return recognizer; } @@ -88,8 +90,8 @@ public class ParamLocationRecognizer implements ParameterParser.Recognizer { /** * Returns the list of ordinal parameter locations. The list elements - * are Integers, representing the location for that given ordinal. Thus - * {@link #getOrdinalParameterLocationList()}.elementAt(n) represents the + * are Integers, representing the location for that given ordinal. Thus calling + * {@code getOrdinalParameterLocationList().elementAt(n)} represents the * location for the nth parameter. * * @return The list of ordinal parameter locations. diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterMetadata.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterMetadata.java index e1e81fe19d..d9c1ce5f26 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterMetadata.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterMetadata.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,9 +20,9 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.engine.query.spi; + import java.io.Serializable; import java.util.HashMap; import java.util.Map; @@ -37,33 +37,35 @@ import org.hibernate.type.Type; * @author Steve Ebersole */ public class ParameterMetadata implements Serializable { - private static final OrdinalParameterDescriptor[] EMPTY_ORDINALS = new OrdinalParameterDescriptor[0]; private final OrdinalParameterDescriptor[] ordinalDescriptors; - private final Map namedDescriptorMap; + private final Map namedDescriptorMap; /** * Instantiates a ParameterMetadata container. * - * @param ordinalDescriptors - * @param namedDescriptorMap + * @param ordinalDescriptors Descriptors of the ordinal parameters + * @param namedDescriptorMap Descriptors of the named parameters */ - public ParameterMetadata(OrdinalParameterDescriptor[] ordinalDescriptors, Map namedDescriptorMap) { + public ParameterMetadata( + OrdinalParameterDescriptor[] ordinalDescriptors, + Map namedDescriptorMap) { if ( ordinalDescriptors == null ) { this.ordinalDescriptors = EMPTY_ORDINALS; } else { - OrdinalParameterDescriptor[] copy = new OrdinalParameterDescriptor[ ordinalDescriptors.length ]; + final OrdinalParameterDescriptor[] copy = new OrdinalParameterDescriptor[ ordinalDescriptors.length ]; System.arraycopy( ordinalDescriptors, 0, copy, 0, ordinalDescriptors.length ); this.ordinalDescriptors = copy; } + if ( namedDescriptorMap == null ) { - this.namedDescriptorMap = java.util.Collections.EMPTY_MAP; + this.namedDescriptorMap = java.util.Collections.emptyMap(); } else { - int size = ( int ) ( ( namedDescriptorMap.size() / .75 ) + 1 ); - Map copy = new HashMap( size ); + final int size = (int) ( ( namedDescriptorMap.size() / .75 ) + 1 ); + final Map copy = new HashMap( size ); copy.putAll( namedDescriptorMap ); this.namedDescriptorMap = java.util.Collections.unmodifiableMap( copy ); } @@ -73,39 +75,107 @@ public class ParameterMetadata implements Serializable { return ordinalDescriptors.length; } + /** + * Get the descriptor for an ordinal parameter given its position + * + * @param position The position (1 based) + * + * @return The ordinal parameter descriptor + * + * @throws QueryParameterException If the position is out of range + */ public OrdinalParameterDescriptor getOrdinalParameterDescriptor(int position) { if ( position < 1 || position > ordinalDescriptors.length ) { - String error = "Position beyond number of declared ordinal parameters. " + - "Remember that ordinal parameters are 1-based! Position: " + position; - throw new QueryParameterException( error ); + throw new QueryParameterException( + "Position beyond number of declared ordinal parameters. " + + "Remember that ordinal parameters are 1-based! Position: " + position + ); } return ordinalDescriptors[position - 1]; } + /** + * Deprecated. + * + * @param position The position + * + * @return The type + * + * @deprecated Use {@link OrdinalParameterDescriptor#getExpectedType()} from the + * {@link #getOrdinalParameterDescriptor} return instead + */ + @Deprecated public Type getOrdinalParameterExpectedType(int position) { return getOrdinalParameterDescriptor( position ).getExpectedType(); } + /** + * Deprecated. + * + * @param position The position + * + * @return The source location + * + * @deprecated Use {@link OrdinalParameterDescriptor#getSourceLocation()} from the + * {@link #getOrdinalParameterDescriptor} return instead + */ + @Deprecated public int getOrdinalParameterSourceLocation(int position) { return getOrdinalParameterDescriptor( position ).getSourceLocation(); } + /** + * Access to the names of all named parameters + * + * @return The named parameter names + */ public Set getNamedParameterNames() { return namedDescriptorMap.keySet(); } + /** + * Get the descriptor for a named parameter given the name + * + * @param name The name of the parameter to locate + * + * @return The named parameter descriptor + * + * @throws QueryParameterException If the name could not be resolved to a named parameter + */ public NamedParameterDescriptor getNamedParameterDescriptor(String name) { - NamedParameterDescriptor meta = ( NamedParameterDescriptor ) namedDescriptorMap.get( name ); + final NamedParameterDescriptor meta = namedDescriptorMap.get( name ); if ( meta == null ) { throw new QueryParameterException( "could not locate named parameter [" + name + "]" ); } return meta; } + /** + * Deprecated. + * + * @param name The name of the parameter + * + * @return The type + * + * @deprecated Use {@link NamedParameterDescriptor#getExpectedType()} from the + * {@link #getNamedParameterDescriptor} return instead + */ + @Deprecated public Type getNamedParameterExpectedType(String name) { return getNamedParameterDescriptor( name ).getExpectedType(); } + /** + * Deprecated. + * + * @param name The name of the parameter + * + * @return The type + * + * @deprecated Use {@link NamedParameterDescriptor#getSourceLocations()} from the + * {@link #getNamedParameterDescriptor} return instead + */ + @Deprecated public int[] getNamedParameterSourceLocations(String name) { return getNamedParameterDescriptor( name ).getSourceLocations(); } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterParser.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterParser.java index b41402d561..a2fb075404 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterParser.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterParser.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,9 +20,9 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.engine.query.spi; + import org.hibernate.QueryException; import org.hibernate.hql.internal.classic.ParserHelper; import org.hibernate.internal.util.StringHelper; @@ -36,12 +36,45 @@ import org.hibernate.internal.util.StringHelper; * @author Steve Ebersole */ public class ParameterParser { - + /** + * Maybe better named a Journaler. Essentially provides a callback contract for things that recognize parameters + */ public static interface Recognizer { + /** + * Called when an output parameter is recognized + * + * @param position The position within the query + */ public void outParameter(int position); + + /** + * Called when an ordinal parameter is recognized + * + * @param position The position within the query + */ public void ordinalParameter(int position); + + /** + * Called when a named parameter is recognized + * + * @param name The recognized parameter name + * @param position The position within the query + */ public void namedParameter(String name, int position); + + /** + * Called when a JPA-style named parameter is recognized + * + * @param name The name of the JPA-style parameter + * @param position The position within the query + */ public void jpaPositionalParameter(String name, int position); + + /** + * Called when a character that is not a parameter (or part of a parameter dfinition) is recognized. + * + * @param character The recognized character + */ public void other(char character); } @@ -64,13 +97,13 @@ public class ParameterParser { * @throws QueryException Indicates unexpected parameter conditions. */ public static void parse(String sqlString, Recognizer recognizer) throws QueryException { - boolean hasMainOutputParameter = startsWithEscapeCallTemplate( sqlString ); + final boolean hasMainOutputParameter = startsWithEscapeCallTemplate( sqlString ); boolean foundMainOutputParam = false; - int stringLength = sqlString.length(); + final int stringLength = sqlString.length(); boolean inQuote = false; for ( int indx = 0; indx < stringLength; indx++ ) { - char c = sqlString.charAt( indx ); + final char c = sqlString.charAt( indx ); if ( inQuote ) { if ( '\'' == c ) { inQuote = false; @@ -88,9 +121,9 @@ public class ParameterParser { else { if ( c == ':' ) { // named parameter - int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS_BITSET, indx + 1 ); - int chopLocation = right < 0 ? sqlString.length() : right; - String param = sqlString.substring( indx + 1, chopLocation ); + final int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS_BITSET, indx + 1 ); + final int chopLocation = right < 0 ? sqlString.length() : right; + final String param = sqlString.substring( indx + 1, chopLocation ); if ( StringHelper.isEmpty( param ) ) { throw new QueryException( "Space is not allowed after parameter prefix ':' [" + sqlString + "]" @@ -103,12 +136,12 @@ public class ParameterParser { // could be either an ordinal or JPA-positional parameter if ( indx < stringLength - 1 && Character.isDigit( sqlString.charAt( indx + 1 ) ) ) { // a peek ahead showed this as an JPA-positional parameter - int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS, indx + 1 ); - int chopLocation = right < 0 ? sqlString.length() : right; - String param = sqlString.substring( indx + 1, chopLocation ); + final int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS, indx + 1 ); + final int chopLocation = right < 0 ? sqlString.length() : right; + final String param = sqlString.substring( indx + 1, chopLocation ); // make sure this "name" is an integral try { - Integer.valueOf( param ); + Integer.valueOf( param ); } catch( NumberFormatException e ) { throw new QueryException( "JPA-style positional param was not an integral ordinal" ); @@ -133,12 +166,19 @@ public class ParameterParser { } } + /** + * Exposed as public solely for use from tests + * + * @param sqlString The SQL string to check + * + * @return true/false + */ public static boolean startsWithEscapeCallTemplate(String sqlString) { if ( ! ( sqlString.startsWith( "{" ) && sqlString.endsWith( "}" ) ) ) { return false; } - int chopLocation = sqlString.indexOf( "call" ); + final int chopLocation = sqlString.indexOf( "call" ); if ( chopLocation <= 0 ) { return false; } @@ -147,7 +187,8 @@ public class ParameterParser { final String fixture = "?=call"; int fixturePosition = 0; boolean matches = true; - for ( int i = 0, max = checkString.length(); i < max; i++ ) { + final int max = checkString.length(); + for ( int i = 0; i < max; i++ ) { final char c = Character.toLowerCase( checkString.charAt( i ) ); if ( Character.isWhitespace( c ) ) { continue; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryMetadata.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryMetadata.java deleted file mode 100644 index ac906d57fd..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryMetadata.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program 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 this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - * - */ -package org.hibernate.engine.query.spi; -import java.io.Serializable; -import java.util.Set; - -import org.hibernate.type.Type; - -/** - * Defines metadata regarding a translated HQL or native-SQL query. - * - * @author Steve Ebersole - */ -public class QueryMetadata implements Serializable { - private final String sourceQuery; - private final ParameterMetadata parameterMetadata; - private final String[] returnAliases; - private final Type[] returnTypes; - private final Set querySpaces; - - public QueryMetadata( - String sourceQuery, - ParameterMetadata parameterMetadata, - String[] returnAliases, - Type[] returnTypes, - Set querySpaces) { - this.sourceQuery = sourceQuery; - this.parameterMetadata = parameterMetadata; - this.returnAliases = returnAliases; - this.returnTypes = returnTypes; - this.querySpaces = querySpaces; - } - - /** - * Get the source HQL or native-SQL query. - * - * @return The source query. - */ - public String getSourceQuery() { - return sourceQuery; - } - - public ParameterMetadata getParameterMetadata() { - return parameterMetadata; - } - - /** - * Return source query select clause aliases (if any) - * - * @return an array of aliases as strings. - */ - public String[] getReturnAliases() { - return returnAliases; - } - - /** - * An array of types describing the returns of the source query. - * - * @return The return type array. - */ - public Type[] getReturnTypes() { - return returnTypes; - } - - /** - * The set of query spaces affected by this source query. - * - * @return The set of query spaces. - */ - public Set getQuerySpaces() { - return querySpaces; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryPlanCache.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryPlanCache.java index d7574e2a85..35c07194e9 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryPlanCache.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryPlanCache.java @@ -28,17 +28,16 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.Map; import java.util.Set; -import org.jboss.logging.Logger; - +import org.hibernate.Filter; import org.hibernate.MappingException; import org.hibernate.QueryException; import org.hibernate.cfg.Environment; import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.FilterImpl; import org.hibernate.internal.util.collections.BoundedConcurrentHashMap; @@ -54,9 +53,8 @@ import org.hibernate.internal.util.config.ConfigurationHelper; * @author Steve Ebersole */ public class QueryPlanCache implements Serializable { + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( QueryPlanCache.class ); - private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, QueryPlanCache.class.getName()); - /** * The default strong reference count. */ @@ -65,11 +63,14 @@ public class QueryPlanCache implements Serializable { * The default soft reference count. */ public static final int DEFAULT_QUERY_PLAN_MAX_COUNT = 2048; + private final SessionFactoryImplementor factory; + /** * the cache of the actual plans... */ private final BoundedConcurrentHashMap queryPlanCache; + /** * simple cache of param metadata based on query string. Ideally, the original "user-supplied query" * string should be used to obtain this metadata (i.e., not the para-list-expanded query string) to avoid @@ -80,6 +81,12 @@ public class QueryPlanCache implements Serializable { */ private final BoundedConcurrentHashMap parameterMetadataCache; + /** + * Constructs the QueryPlanCache to be used by the given SessionFactory + * + * @param factory The SessionFactory + */ + @SuppressWarnings("deprecation") public QueryPlanCache(final SessionFactoryImplementor factory) { this.factory = factory; @@ -135,15 +142,17 @@ public class QueryPlanCache implements Serializable { } private ParameterMetadata buildParameterMetadata(String query){ - ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( query ); + final ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( query ); + final int size = recognizer.getOrdinalParameterLocationList().size(); - OrdinalParameterDescriptor[] ordinalDescriptors = new OrdinalParameterDescriptor[ size ]; + final OrdinalParameterDescriptor[] ordinalDescriptors = new OrdinalParameterDescriptor[ size ]; for ( int i = 0; i < size; i++ ) { final Integer position = recognizer.getOrdinalParameterLocationList().get( i ); ordinalDescriptors[i] = new OrdinalParameterDescriptor( i, null, position ); } - Map namedParamDescriptorMap = new HashMap(); - Map map = recognizer.getNamedParameterDescriptionMap(); + + final Map namedParamDescriptorMap = new HashMap(); + final Map map = recognizer.getNamedParameterDescriptionMap(); for ( final String name : map.keySet() ) { final ParamLocationRecognizer.NamedParameterDescription description = map.get( name ); namedParamDescriptorMap.put( @@ -159,9 +168,22 @@ public class QueryPlanCache implements Serializable { return new ParameterMetadata( ordinalDescriptors, namedParamDescriptorMap ); } - public HQLQueryPlan getHQLQueryPlan( String queryString, boolean shallow, Map enabledFilters) + /** + * Get the query plan for the given HQL query, creating it and caching it if not already cached + * + * @param queryString The HQL query string + * @param shallow Whether the execution will be shallow + * @param enabledFilters The filters enabled on the Session + * + * @return The query plan + * + * @throws QueryException Indicates a problem translating the query + * @throws MappingException Indicates a problem translating the query + */ + @SuppressWarnings("unchecked") + public HQLQueryPlan getHQLQueryPlan(String queryString, boolean shallow, Map enabledFilters) throws QueryException, MappingException { - HQLQueryPlanKey key = new HQLQueryPlanKey( queryString, shallow, enabledFilters ); + final HQLQueryPlanKey key = new HQLQueryPlanKey( queryString, shallow, enabledFilters ); HQLQueryPlan value = (HQLQueryPlan) queryPlanCache.get( key ); if ( value == null ) { LOG.tracev( "Unable to locate HQL query plan in cache; generating ({0})", queryString ); @@ -173,37 +195,69 @@ public class QueryPlanCache implements Serializable { return value; } - - - public FilterQueryPlan getFilterQueryPlan(String filterString, String collectionRole, boolean shallow, Map enabledFilters) - throws QueryException, MappingException { - FilterQueryPlanKey key = new FilterQueryPlanKey( filterString, collectionRole, shallow, enabledFilters ); + /** + * Get the query plan for the given collection HQL filter fragment, creating it and caching it if not already cached + * + * @param filterString The HQL filter fragment + * @param collectionRole The collection being filtered + * @param shallow Whether the execution will be shallow + * @param enabledFilters The filters enabled on the Session + * + * @return The query plan + * + * @throws QueryException Indicates a problem translating the query + * @throws MappingException Indicates a problem translating the query + */ + @SuppressWarnings("unchecked") + public FilterQueryPlan getFilterQueryPlan( + String filterString, + String collectionRole, + boolean shallow, + Map enabledFilters) throws QueryException, MappingException { + final FilterQueryPlanKey key = new FilterQueryPlanKey( filterString, collectionRole, shallow, enabledFilters ); FilterQueryPlan value = (FilterQueryPlan) queryPlanCache.get( key ); - if(value == null){ - LOG.tracev( "Unable to locate collection-filter query plan in cache; generating ({0} : {1} )", - collectionRole, filterString ); + if ( value == null ) { + LOG.tracev( + "Unable to locate collection-filter query plan in cache; generating ({0} : {1} )", + collectionRole, + filterString + ); value = new FilterQueryPlan( filterString, collectionRole, shallow, enabledFilters,factory ); queryPlanCache.putIfAbsent( key, value ); - } else { + } + else { LOG.tracev( "Located collection-filter query plan in cache ({0} : {1})", collectionRole, filterString ); } return value; } + /** + * Get the query plan for a native SQL query, creating it and caching it if not already cached + * + * @param spec The native SQL query specification + * + * @return The query plan + * + * @throws QueryException Indicates a problem translating the query + * @throws MappingException Indicates a problem translating the query + */ + @SuppressWarnings("unchecked") public NativeSQLQueryPlan getNativeSQLQueryPlan(final NativeSQLQuerySpecification spec) { NativeSQLQueryPlan value = (NativeSQLQueryPlan) queryPlanCache.get( spec ); - if(value == null){ + if ( value == null ) { LOG.tracev( "Unable to locate native-sql query plan in cache; generating ({0})", spec.getQueryString() ); value = new NativeSQLQueryPlan( spec, factory); queryPlanCache.putIfAbsent( spec, value ); - } else { + } + else { LOG.tracev( "Located native-sql query plan in cache ({0})", spec.getQueryString() ); } return value; } - - //clean up QueryPlanCache when Sessionfactory is closed + /** + * clean up QueryPlanCache when SessionFactory is closed + */ public void cleanup() { LOG.trace( "Cleaning QueryPlan Cache" ); queryPlanCache.clear(); @@ -223,7 +277,7 @@ public class QueryPlanCache implements Serializable { filterKeys = Collections.emptySet(); } else { - Set tmp = new HashSet( + final Set tmp = new HashSet( CollectionHelper.determineProperSizing( enabledFilters ), CollectionHelper.LOAD_FACTOR ); @@ -248,7 +302,7 @@ public class QueryPlanCache implements Serializable { return false; } - final HQLQueryPlanKey that = ( HQLQueryPlanKey ) o; + final HQLQueryPlanKey that = (HQLQueryPlanKey) o; return shallow == that.shallow && filterKeys.equals( that.filterKeys ) @@ -306,8 +360,7 @@ public class QueryPlanCache implements Serializable { return false; } - DynamicFilterKey that = ( DynamicFilterKey ) o; - + final DynamicFilterKey that = (DynamicFilterKey) o; return filterName.equals( that.filterName ) && parameterMetadata.equals( that.parameterMetadata ); @@ -336,7 +389,7 @@ public class QueryPlanCache implements Serializable { this.filterNames = Collections.emptySet(); } else { - Set tmp = new HashSet(); + final Set tmp = new HashSet(); tmp.addAll( enabledFilters.keySet() ); this.filterNames = Collections.unmodifiableSet( tmp ); @@ -358,8 +411,7 @@ public class QueryPlanCache implements Serializable { return false; } - final FilterQueryPlanKey that = ( FilterQueryPlanKey ) o; - + final FilterQueryPlanKey that = (FilterQueryPlanKey) o; return shallow == that.shallow && filterNames.equals( that.filterNames ) && query.equals( that.query ) diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ReturnMetadata.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ReturnMetadata.java index bd9c2b1d71..4378bcde0a 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ReturnMetadata.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ReturnMetadata.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,21 +20,23 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.engine.query.spi; + import java.io.Serializable; import org.hibernate.type.Type; /** + * Metadata about the query return(s). + * * @author Steve Ebersole */ public class ReturnMetadata implements Serializable { private final String[] returnAliases; private final Type[] returnTypes; - public ReturnMetadata(String[] returnAliases, Type[] returnTypes) { + ReturnMetadata(String[] returnAliases, Type[] returnTypes) { this.returnAliases = returnAliases; this.returnTypes = returnTypes; } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/package-info.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/package-info.java new file mode 100644 index 0000000000..24cf9b0273 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/package-info.java @@ -0,0 +1,4 @@ +/** + * Defines support for query plans and stored metadata about queries + */ +package org.hibernate.engine.query.spi;