All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.engine.spi.LoadQueryInfluencers Maven / Gradle / Ivy

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or .
 */
package org.hibernate.engine.spi;

import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.persistence.EntityGraph;

import org.hibernate.Filter;
import org.hibernate.UnknownProfileException;
import org.hibernate.graph.GraphSemantic;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.internal.FilterImpl;
import org.hibernate.type.Type;

/**
 * Centralize all options which can influence the SQL query needed to load an
 * entity.  Currently such influencers are defined as:
    *
  • filters
  • *
  • fetch profiles
  • *
  • internal fetch profile (merge profile, etc)
  • *
* * @author Steve Ebersole */ public class LoadQueryInfluencers implements Serializable { /** * Static reference useful for cases where we are creating load SQL * outside the context of any influencers. One such example is * anything created by the session factory. */ public static final LoadQueryInfluencers NONE = new LoadQueryInfluencers(); private final SessionFactoryImplementor sessionFactory; private String internalFetchProfile; private final Set enabledFetchProfileNames; private final Map enabledFilters; private final EffectiveEntityGraph effectiveEntityGraph = new EffectiveEntityGraph(); public LoadQueryInfluencers() { this( null ); } public LoadQueryInfluencers(SessionFactoryImplementor sessionFactory) { this( sessionFactory, new HashMap<>(), new HashSet<>() ); } private LoadQueryInfluencers(SessionFactoryImplementor sessionFactory, Map enabledFilters, Set enabledFetchProfileNames) { this.sessionFactory = sessionFactory; this.enabledFilters = enabledFilters; this.enabledFetchProfileNames = enabledFetchProfileNames; } public SessionFactoryImplementor getSessionFactory() { return sessionFactory; } // internal fetch profile support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public String getInternalFetchProfile() { return internalFetchProfile; } public void setInternalFetchProfile(String internalFetchProfile) { if ( sessionFactory == null ) { // thats the signal that this is the immutable, context-less // variety throw new IllegalStateException( "Cannot modify context-less LoadQueryInfluencers" ); } this.internalFetchProfile = internalFetchProfile; } // filter support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public boolean hasEnabledFilters() { return !enabledFilters.isEmpty(); } public Map getEnabledFilters() { // First, validate all the enabled filters... //TODO: this implementation has bad performance for ( Filter filter : enabledFilters.values() ) { filter.validate(); } return enabledFilters; } /** * Returns an unmodifiable Set of enabled filter names. * @return an unmodifiable Set of enabled filter names. */ public Set getEnabledFilterNames() { return java.util.Collections.unmodifiableSet( enabledFilters.keySet() ); } public Filter getEnabledFilter(String filterName) { return enabledFilters.get( filterName ); } public Filter enableFilter(String filterName) { FilterImpl filter = new FilterImpl( sessionFactory.getFilterDefinition( filterName ) ); enabledFilters.put( filterName, filter ); return filter; } public void disableFilter(String filterName) { enabledFilters.remove( filterName ); } public Object getFilterParameterValue(String filterParameterName) { final String[] parsed = parseFilterParameterName( filterParameterName ); final FilterImpl filter = (FilterImpl) enabledFilters.get( parsed[0] ); if ( filter == null ) { throw new IllegalArgumentException( "Filter [" + parsed[0] + "] currently not enabled" ); } return filter.getParameter( parsed[1] ); } public Type getFilterParameterType(String filterParameterName) { final String[] parsed = parseFilterParameterName( filterParameterName ); final FilterDefinition filterDef = sessionFactory.getFilterDefinition( parsed[0] ); if ( filterDef == null ) { throw new IllegalArgumentException( "Filter [" + parsed[0] + "] not defined" ); } final Type type = filterDef.getParameterType( parsed[1] ); if ( type == null ) { // this is an internal error of some sort... throw new InternalError( "Unable to locate type for filter parameter" ); } return type; } public static String[] parseFilterParameterName(String filterParameterName) { int dot = filterParameterName.lastIndexOf( '.' ); if ( dot <= 0 ) { throw new IllegalArgumentException( "Invalid filter-parameter name format [" + filterParameterName + "]; expecting {filter-name}.{param-name}" ); } final String filterName = filterParameterName.substring( 0, dot ); final String parameterName = filterParameterName.substring( dot + 1 ); return new String[] { filterName, parameterName }; } // fetch profile support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public boolean hasEnabledFetchProfiles() { return !enabledFetchProfileNames.isEmpty(); } public Set getEnabledFetchProfileNames() { return enabledFetchProfileNames; } private void checkFetchProfileName(String name) { if ( !sessionFactory.containsFetchProfileDefinition( name ) ) { throw new UnknownProfileException( name ); } } public boolean isFetchProfileEnabled(String name) throws UnknownProfileException { checkFetchProfileName( name ); return enabledFetchProfileNames.contains( name ); } public void enableFetchProfile(String name) throws UnknownProfileException { checkFetchProfileName( name ); enabledFetchProfileNames.add( name ); } public void disableFetchProfile(String name) throws UnknownProfileException { checkFetchProfileName( name ); enabledFetchProfileNames.remove( name ); } public EffectiveEntityGraph getEffectiveEntityGraph() { return effectiveEntityGraph; } /** * @deprecated (since 5.4) {@link #getFetchGraph}, {@link #getLoadGraph}, {@link #setFetchGraph} * and {@link #setLoadGraph} (as well as JPA itself honestly) all make it very unclear that * there can be only one graph applied at any one time and that graph is *either* a load or * a fetch graph. These have all been replaced with {@link #getEffectiveEntityGraph()}. * * @see EffectiveEntityGraph */ @Deprecated public EntityGraph getFetchGraph() { if ( effectiveEntityGraph.getSemantic() != GraphSemantic.FETCH ) { return null; } return effectiveEntityGraph.getGraph(); } /** * @deprecated (since 5.4) {@link #getFetchGraph}, {@link #getLoadGraph}, {@link #setFetchGraph} * and {@link #setLoadGraph} (as well as JPA itself honestly) all make it very unclear that * there can be only one graph applied at any one time and that graph is *either* a load or * a fetch graph. These have all been replaced with {@link #getEffectiveEntityGraph()}. * * @see EffectiveEntityGraph */ @Deprecated public void setFetchGraph(EntityGraph fetchGraph) { effectiveEntityGraph.applyGraph( (RootGraphImplementor) fetchGraph, GraphSemantic.FETCH ); } /** * @deprecated (since 5.4) {@link #getFetchGraph}, {@link #getLoadGraph}, {@link #setFetchGraph} * and {@link #setLoadGraph} (as well as JPA itself honestly) all make it very unclear that * there can be only one graph applied at any one time and that graph is *either* a load or * a fetch graph. These have all been replaced with {@link #getEffectiveEntityGraph()}. * * @see EffectiveEntityGraph */ @Deprecated public EntityGraph getLoadGraph() { if ( effectiveEntityGraph.getSemantic() != GraphSemantic.LOAD ) { return null; } return effectiveEntityGraph.getGraph(); } /** * @deprecated (since 5.4) {@link #getFetchGraph}, {@link #getLoadGraph}, {@link #setFetchGraph} * and {@link #setLoadGraph} (as well as JPA itself honestly) all make it very unclear that * there can be only one graph applied at any one time and that that graph is *either* a load or * a fetch graph. These have all been replaced with {@link #getEffectiveEntityGraph()}. * * @see EffectiveEntityGraph */ @Deprecated public void setLoadGraph(final EntityGraph loadGraph) { effectiveEntityGraph.applyGraph( (RootGraphImplementor) loadGraph, GraphSemantic.LOAD ); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy