HHH-10563 : Significant String use/duplication associated with subselect fetch

(cherry picked from commit 3f37fff04a)

Conflicts:
	hibernate-core/src/main/java/org/hibernate/engine/spi/SubselectFetch.java
	hibernate-core/src/main/java/org/hibernate/loader/Loader.java
	hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/internal/ResultSetProcessingContextImpl.java
This commit is contained in:
Gail Badner 2016-03-01 18:38:17 -08:00
parent 8fb8a158d3
commit 0d5c35cdbc
2 changed files with 77 additions and 13 deletions

View File

@ -48,30 +48,92 @@ public class SubselectFetch {
private final QueryParameters queryParameters;
private final Map namedParameterLocMap;
/**
* Construct a SubselectFetch instance. The subselect fetch query fragment is generated by
* {@link #createSubselectFetchQueryFragment}.
*
* If the same value for {@code queryParameters} is to be used when constructing multiple
* SubselectFetch objects, then it is preferable to generate the subselect fetch query
* fragment using {@link #createSubselectFetchQueryFragment}, and pass the result as an
* argument to constructor {@link #SubselectFetch(String, String, Loadable, QueryParameters, Set, Map)}.
*
* @param alias - the table alias used in the subselect fetch query fragment
* (to be generated by {@link #createSubselectFetchQueryFragment(QueryParameters)} that
* corresponds to {@code loadable};
* @param loadable - the {@link Loadable} for the associated entities to be subselect fetched;
* @param queryParameters - the query parameters;
* @param resultingEntityKeys - the {@link EntityKey} objects for the entities to be subselect fetched;
* @param namedParameterLocMap - mapping from named parameter to the parameter index located in the
* subselect fetch query fragment.
*
* @see #SubselectFetch(String, String, Loadable, QueryParameters, Set, Map)
*/
public SubselectFetch(
//final String queryString,
final String alias,
final Loadable loadable,
final QueryParameters queryParameters,
final Set resultingEntityKeys,
final Map namedParameterLocMap
) {
final String alias,
final Loadable loadable,
final QueryParameters queryParameters,
final Set resultingEntityKeys,
final Map namedParameterLocMap) {
this(
createSubselectFetchQueryFragment( queryParameters ),
alias,
loadable,
queryParameters,
resultingEntityKeys,
namedParameterLocMap
);
}
/**
* Construct a SubselectFetch instance using the provided subselect fetch query fragment,
* {@code subselectFetchQueryFragment}. It is assumed that {@code subselectFetchQueryFragment}
* is the result of calling {@link #createSubselectFetchQueryFragment} with the same value
* provided for {@code queryParameters}.
*
* @param subselectFetchQueryFragment - the subselect fetch query fragment;
* @param alias - the table alias used in {@code subselectFetchQueryFragment} that
* corresponds to {@code loadable};
* @param loadable - the {@link Loadable} for the associated entities to be subselect fetched;
* @param queryParameters - the query parameters;
* @param resultingEntityKeys - the {@link EntityKey} objects for the entities to be subselect fetched;
* @param namedParameterLocMap - mapping from named parameter to the parameter index located in the
* subselect fetch query fragment.
*/
public SubselectFetch(
final String subselectFetchQueryFragment,
final String alias,
final Loadable loadable,
final QueryParameters queryParameters,
final Set resultingEntityKeys,
final Map namedParameterLocMap) {
this.resultingEntityKeys = resultingEntityKeys;
this.queryParameters = queryParameters;
this.namedParameterLocMap = namedParameterLocMap;
this.loadable = loadable;
this.alias = alias;
this.queryString = subselectFetchQueryFragment;
}
/**
* Create the subselect fetch query fragment for the provided {@link QueryParameters}
* with SELECT and ORDER BY clauses removed.
*
* @param queryParameters -the query parameters.
* @return the subselect fetch query fragment.
*/
public static String createSubselectFetchQueryFragment(QueryParameters queryParameters) {
//TODO: ugly here:
final String queryString = queryParameters.getFilteredSQL();
int fromIndex = queryString.indexOf(" from ");
int orderByIndex = queryString.lastIndexOf("order by");
this.queryString = orderByIndex>0 ?
queryString.substring(fromIndex, orderByIndex) :
queryString.substring(fromIndex);
final String subselectQueryFragment = orderByIndex > 0
? queryString.substring( fromIndex, orderByIndex )
: queryString.substring( fromIndex );
if ( LOG.isTraceEnabled() ) {
LOG.tracef( "Generated SubselectFetch query: %s", queryString );
LOG.tracef( "SubselectFetch query fragment: %s", subselectQueryFragment );
}
return subselectQueryFragment;
}
public QueryParameters getQueryParameters() {

View File

@ -63,7 +63,6 @@ import org.hibernate.dialect.pagination.NoopLimitHandler;
import org.hibernate.engine.internal.CacheHelper;
import org.hibernate.engine.internal.TwoPhaseLoad;
import org.hibernate.engine.jdbc.ColumnNameCache;
import org.hibernate.engine.jdbc.spi.ResultSetWrapper;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.EntityUniqueKey;
@ -1014,6 +1013,9 @@ public abstract class Loader {
final Loadable[] loadables = getEntityPersisters();
final String[] aliases = getAliases();
final String subselectQueryString = SubselectFetch.createSubselectFetchQueryFragment(
queryParameters
);
final Iterator iter = keys.iterator();
while ( iter.hasNext() ) {
@ -1023,7 +1025,7 @@ public abstract class Loader {
if ( rowKeys[i]!=null && loadables[i].hasSubselectLoadableCollections() ) {
SubselectFetch subselectFetch = new SubselectFetch(
//getSQLString(),
subselectQueryString,
aliases[i],
loadables[i],
queryParameters,