org.hibernate.query.spi.NamedQueryRepository Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core Show documentation
Show all versions of hibernate-core Show documentation
The core O/RM functionality as provided by Hibernate
/*
* 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.query.spi;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.MappingException;
import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.query.spi.QueryPlanCache;
import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification;
import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.procedure.ProcedureCallMemento;
import org.jboss.logging.Logger;
/**
* @author Steve Ebersole
*/
@Incubating
public class NamedQueryRepository {
private static final Logger log = Logger.getLogger( NamedQueryRepository.class );
private final Map namedSqlResultSetMappingMap;
private volatile Map namedQueryDefinitionMap;
private volatile Map namedSqlQueryDefinitionMap;
private volatile Map procedureCallMementoMap;
public NamedQueryRepository(
Iterable namedQueryDefinitions,
Iterable namedSqlQueryDefinitions,
Iterable namedSqlResultSetMappings,
Map namedProcedureCalls) {
final HashMap namedQueryDefinitionMap = new HashMap();
for ( NamedQueryDefinition namedQueryDefinition : namedQueryDefinitions ) {
namedQueryDefinitionMap.put( namedQueryDefinition.getName(), namedQueryDefinition );
}
this.namedQueryDefinitionMap = Collections.unmodifiableMap( namedQueryDefinitionMap );
final HashMap namedSqlQueryDefinitionMap = new HashMap();
for ( NamedSQLQueryDefinition namedSqlQueryDefinition : namedSqlQueryDefinitions ) {
namedSqlQueryDefinitionMap.put( namedSqlQueryDefinition.getName(), namedSqlQueryDefinition );
}
this.namedSqlQueryDefinitionMap = Collections.unmodifiableMap( namedSqlQueryDefinitionMap );
final HashMap namedSqlResultSetMappingMap = new HashMap();
for ( ResultSetMappingDefinition resultSetMappingDefinition : namedSqlResultSetMappings ) {
namedSqlResultSetMappingMap.put( resultSetMappingDefinition.getName(), resultSetMappingDefinition );
}
this.namedSqlResultSetMappingMap = Collections.unmodifiableMap( namedSqlResultSetMappingMap );
this.procedureCallMementoMap = Collections.unmodifiableMap( namedProcedureCalls );
}
public NamedQueryRepository(
Map namedQueryDefinitionMap,
Map namedSqlQueryDefinitionMap,
Map namedSqlResultSetMappingMap,
Map namedProcedureCallMap) {
this.namedQueryDefinitionMap = Collections.unmodifiableMap( namedQueryDefinitionMap );
this.namedSqlQueryDefinitionMap = Collections.unmodifiableMap( namedSqlQueryDefinitionMap );
this.namedSqlResultSetMappingMap = Collections.unmodifiableMap( namedSqlResultSetMappingMap );
this.procedureCallMementoMap = Collections.unmodifiableMap( namedProcedureCallMap );
}
public NamedQueryDefinition getNamedQueryDefinition(String queryName) {
return namedQueryDefinitionMap.get( queryName );
}
public NamedSQLQueryDefinition getNamedSQLQueryDefinition(String queryName) {
return namedSqlQueryDefinitionMap.get( queryName );
}
public ProcedureCallMemento getNamedProcedureCallMemento(String name) {
return procedureCallMementoMap.get( name );
}
public ResultSetMappingDefinition getResultSetMappingDefinition(String mappingName) {
return namedSqlResultSetMappingMap.get( mappingName );
}
public synchronized void registerNamedQueryDefinition(String name, NamedQueryDefinition definition) {
if ( NamedSQLQueryDefinition.class.isInstance( definition ) ) {
throw new IllegalArgumentException( "NamedSQLQueryDefinition instance incorrectly passed to registerNamedQueryDefinition" );
}
if ( ! name.equals( definition.getName() ) ) {
definition = definition.makeCopy( name );
}
final Map copy = CollectionHelper.makeCopy( namedQueryDefinitionMap );
final NamedQueryDefinition previous = copy.put( name, definition );
if ( previous != null ) {
log.debugf(
"registering named query definition [%s] overriding previously registered definition [%s]",
name,
previous
);
}
this.namedQueryDefinitionMap = Collections.unmodifiableMap( copy );
}
public synchronized void registerNamedSQLQueryDefinition(String name, NamedSQLQueryDefinition definition) {
if ( ! name.equals( definition.getName() ) ) {
definition = definition.makeCopy( name );
}
final Map copy = CollectionHelper.makeCopy( namedSqlQueryDefinitionMap );
final NamedQueryDefinition previous = copy.put( name, definition );
if ( previous != null ) {
log.debugf(
"registering named SQL query definition [%s] overriding previously registered definition [%s]",
name,
previous
);
}
this.namedSqlQueryDefinitionMap = Collections.unmodifiableMap( copy );
}
public synchronized void registerNamedProcedureCallMemento(String name, ProcedureCallMemento memento) {
final Map copy = CollectionHelper.makeCopy( procedureCallMementoMap );
final ProcedureCallMemento previous = copy.put( name, memento );
if ( previous != null ) {
log.debugf(
"registering named procedure call definition [%s] overriding previously registered definition [%s]",
name,
previous
);
}
this.procedureCallMementoMap = Collections.unmodifiableMap( copy );
}
public Map checkNamedQueries(QueryPlanCache queryPlanCache) {
Map errors = new HashMap();
// Check named HQL queries
log.debugf( "Checking %s named HQL queries", namedQueryDefinitionMap.size() );
for ( NamedQueryDefinition namedQueryDefinition : namedQueryDefinitionMap.values() ) {
// this will throw an error if there's something wrong.
try {
log.debugf( "Checking named query: %s", namedQueryDefinition.getName() );
//TODO: BUG! this currently fails for named queries for non-POJO entities
queryPlanCache.getHQLQueryPlan( namedQueryDefinition.getQueryString(), false, Collections.EMPTY_MAP );
}
catch ( HibernateException e ) {
errors.put( namedQueryDefinition.getName(), e );
}
}
// Check native-sql queries
log.debugf( "Checking %s named SQL queries", namedSqlQueryDefinitionMap.size() );
for ( NamedSQLQueryDefinition namedSQLQueryDefinition : namedSqlQueryDefinitionMap.values() ) {
// this will throw an error if there's something wrong.
try {
log.debugf( "Checking named SQL query: %s", namedSQLQueryDefinition.getName() );
// TODO : would be really nice to cache the spec on the query-def so as to not have to re-calc the hash;
// currently not doable though because of the resultset-ref stuff...
NativeSQLQuerySpecification spec;
if ( namedSQLQueryDefinition.getResultSetRef() != null ) {
ResultSetMappingDefinition definition = getResultSetMappingDefinition( namedSQLQueryDefinition.getResultSetRef() );
if ( definition == null ) {
throw new MappingException( "Unable to find resultset-ref definition: " + namedSQLQueryDefinition.getResultSetRef() );
}
spec = new NativeSQLQuerySpecification(
namedSQLQueryDefinition.getQueryString(),
definition.getQueryReturns(),
namedSQLQueryDefinition.getQuerySpaces()
);
}
else {
spec = new NativeSQLQuerySpecification(
namedSQLQueryDefinition.getQueryString(),
namedSQLQueryDefinition.getQueryReturns(),
namedSQLQueryDefinition.getQuerySpaces()
);
}
queryPlanCache.getNativeSQLQueryPlan( spec );
}
catch ( HibernateException e ) {
errors.put( namedSQLQueryDefinition.getName(), e );
}
}
return errors;
}
}