HHH-8222 - Implement @NamedStoredProcedureQuery binding
This commit is contained in:
parent
40373412e0
commit
8c95a6077a
|
@ -26,6 +26,7 @@ package org.hibernate;
|
|||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.procedure.ProcedureCallMemento;
|
||||
|
||||
/**
|
||||
* Contract methods shared between {@link Session} and {@link StatelessSession}.
|
||||
|
@ -86,6 +87,17 @@ public interface SharedSessionContract extends Serializable {
|
|||
*/
|
||||
public SQLQuery createSQLQuery(String queryString);
|
||||
|
||||
/**
|
||||
* Gets a ProcedureCall based on a named template
|
||||
*
|
||||
* @param name The name given to the template
|
||||
*
|
||||
* @return The ProcedureCall
|
||||
*
|
||||
* @see javax.persistence.NamedStoredProcedureQuery
|
||||
*/
|
||||
public ProcedureCall getNamedProcedureCall(String name);
|
||||
|
||||
/**
|
||||
* Creates a call to a stored procedure.
|
||||
*
|
||||
|
@ -154,5 +166,4 @@ public interface SharedSessionContract extends Serializable {
|
|||
* @return The criteria instance for manipulation and execution
|
||||
*/
|
||||
public Criteria createCriteria(String entityName, String alias);
|
||||
|
||||
}
|
||||
|
|
|
@ -68,6 +68,8 @@ import javax.persistence.NamedNativeQueries;
|
|||
import javax.persistence.NamedNativeQuery;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.NamedStoredProcedureQueries;
|
||||
import javax.persistence.NamedStoredProcedureQuery;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.OrderColumn;
|
||||
|
@ -253,6 +255,28 @@ public final class AnnotationBinder {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
final List<NamedStoredProcedureQuery> annotations =
|
||||
(List<NamedStoredProcedureQuery>) defaults.get( NamedStoredProcedureQuery.class );
|
||||
if ( annotations != null ) {
|
||||
for ( NamedStoredProcedureQuery annotation : annotations ) {
|
||||
QueryBinder.bindNamedStoredProcedureQuery( annotation, mappings );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
final List<NamedStoredProcedureQueries> annotations =
|
||||
(List<NamedStoredProcedureQueries>) defaults.get( NamedStoredProcedureQueries.class );
|
||||
if ( annotations != null ) {
|
||||
for ( NamedStoredProcedureQueries annotation : annotations ) {
|
||||
for ( NamedStoredProcedureQuery queryAnnotation : annotation.value() ) {
|
||||
QueryBinder.bindNamedStoredProcedureQuery( queryAnnotation, mappings );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void bindPackage(String packageName, Mappings mappings) {
|
||||
|
@ -358,6 +382,24 @@ public final class AnnotationBinder {
|
|||
);
|
||||
QueryBinder.bindNativeQueries( ann, mappings );
|
||||
}
|
||||
|
||||
// NamedStoredProcedureQuery handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
{
|
||||
final NamedStoredProcedureQuery annotation = annotatedElement.getAnnotation( NamedStoredProcedureQuery.class );
|
||||
if ( annotation != null ) {
|
||||
QueryBinder.bindNamedStoredProcedureQuery( annotation, mappings );
|
||||
}
|
||||
}
|
||||
|
||||
// NamedStoredProcedureQueries handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
{
|
||||
final NamedStoredProcedureQueries annotation = annotatedElement.getAnnotation( NamedStoredProcedureQueries.class );
|
||||
if ( annotation != null ) {
|
||||
for ( NamedStoredProcedureQuery queryAnnotation : annotation.value() ) {
|
||||
QueryBinder.bindNamedStoredProcedureQuery( queryAnnotation, mappings );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IdGenerator buildIdGenerator(java.lang.annotation.Annotation ann, Mappings mappings) {
|
||||
|
|
|
@ -81,6 +81,7 @@ import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
|
|||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl;
|
||||
import org.hibernate.cfg.annotations.NamedProcedureCallDefinition;
|
||||
import org.hibernate.cfg.annotations.reflection.JPAMetadataProvider;
|
||||
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
|
@ -214,6 +215,7 @@ public class Configuration implements Serializable {
|
|||
|
||||
protected Map<String, NamedQueryDefinition> namedQueries;
|
||||
protected Map<String, NamedSQLQueryDefinition> namedSqlQueries;
|
||||
protected Map<String, NamedProcedureCallDefinition> namedProcedureCallMap;
|
||||
protected Map<String, ResultSetMappingDefinition> sqlResultSetMappings;
|
||||
|
||||
protected Map<String, TypeDef> typeDefs;
|
||||
|
@ -1772,6 +1774,10 @@ public class Configuration implements Serializable {
|
|||
return namedQueries;
|
||||
}
|
||||
|
||||
public Map<String, NamedProcedureCallDefinition> getNamedProcedureCallMap() {
|
||||
return namedProcedureCallMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link SessionFactory} using the properties and mappings in this configuration. The
|
||||
* {@link SessionFactory} will be immutable, so changes made to {@code this} {@link Configuration} after
|
||||
|
@ -2870,6 +2876,16 @@ public class Configuration implements Serializable {
|
|||
namedSqlQueries.put( name.intern(), query );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNamedProcedureCallDefinition(NamedProcedureCallDefinition definition)
|
||||
throws DuplicateMappingException {
|
||||
final String name = definition.getRegisteredName();
|
||||
final NamedProcedureCallDefinition previous = namedProcedureCallMap.put( name, definition );
|
||||
if ( previous != null ) {
|
||||
throw new DuplicateMappingException( "named stored procedure query", name );
|
||||
}
|
||||
}
|
||||
|
||||
public void addDefaultSQLQuery(String name, NamedSQLQueryDefinition query) {
|
||||
applySQLQuery( name, query );
|
||||
defaultNamedNativeQueryNames.add( name );
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.hibernate.MappingException;
|
|||
import org.hibernate.annotations.AnyMetaDef;
|
||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
||||
import org.hibernate.annotations.common.reflection.XClass;
|
||||
import org.hibernate.cfg.annotations.NamedProcedureCallDefinition;
|
||||
import org.hibernate.engine.ResultSetMappingDefinition;
|
||||
import org.hibernate.engine.spi.FilterDefinition;
|
||||
import org.hibernate.engine.spi.NamedQueryDefinition;
|
||||
|
@ -338,6 +339,15 @@ public interface Mappings {
|
|||
*/
|
||||
public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws DuplicateMappingException;
|
||||
|
||||
/**
|
||||
* Adds metadata for a named stored procedure call to this repository.
|
||||
*
|
||||
* @param definition The procedure call information
|
||||
*
|
||||
* @throws DuplicateMappingException If a query already exists with that name.
|
||||
*/
|
||||
public void addNamedProcedureCallDefinition(NamedProcedureCallDefinition definition) throws DuplicateMappingException;
|
||||
|
||||
/**
|
||||
* Get the metadata for a named SQL result set mapping.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
package org.hibernate.cfg.annotations;
|
||||
|
||||
import javax.persistence.NamedStoredProcedureQuery;
|
||||
import javax.persistence.ParameterMode;
|
||||
import javax.persistence.QueryHint;
|
||||
import javax.persistence.StoredProcedureParameter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.engine.ResultSetMappingDefinition;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.SessionFactoryImpl;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.procedure.ProcedureCallMemento;
|
||||
import org.hibernate.procedure.internal.ParameterStrategy;
|
||||
import org.hibernate.procedure.internal.ProcedureCallMementoImpl;
|
||||
import org.hibernate.procedure.internal.Util;
|
||||
|
||||
import static org.hibernate.procedure.internal.ProcedureCallMementoImpl.ParameterMemento;
|
||||
|
||||
/**
|
||||
* Holds all the information needed from a named procedure call declaration in order to create a
|
||||
* {@link org.hibernate.procedure.internal.ProcedureCallImpl}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*
|
||||
* @see javax.persistence.NamedStoredProcedureQuery
|
||||
*/
|
||||
public class NamedProcedureCallDefinition {
|
||||
private final String registeredName;
|
||||
private final String procedureName;
|
||||
private final Class[] resultClasses;
|
||||
private final String[] resultSetMappings;
|
||||
private final ParameterDefinitions parameterDefinitions;
|
||||
private final Map<String,Object> hints;
|
||||
|
||||
NamedProcedureCallDefinition(NamedStoredProcedureQuery annotation) {
|
||||
this.registeredName = annotation.name();
|
||||
this.procedureName = annotation.procedureName();
|
||||
this.resultClasses = annotation.resultClasses();
|
||||
this.resultSetMappings = annotation.resultSetMappings();
|
||||
this.parameterDefinitions = new ParameterDefinitions( annotation.parameters() );
|
||||
this.hints = extract( annotation.hints() );
|
||||
|
||||
final boolean specifiesResultClasses = resultClasses != null && resultClasses.length > 0;
|
||||
final boolean specifiesResultSetMappings = resultSetMappings != null && resultSetMappings.length > 0;
|
||||
|
||||
if ( specifiesResultClasses && specifiesResultSetMappings ) {
|
||||
throw new MappingException(
|
||||
String.format(
|
||||
"NamedStoredProcedureQuery [%s] specified both resultClasses and resultSetMappings",
|
||||
registeredName
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> extract(QueryHint[] hints) {
|
||||
if ( hints == null || hints.length == 0 ) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
final Map<String,Object> hintsMap = new HashMap<String, Object>();
|
||||
for ( QueryHint hint : hints ) {
|
||||
hintsMap.put( hint.name(), hint.value() );
|
||||
}
|
||||
return hintsMap;
|
||||
}
|
||||
|
||||
public String getRegisteredName() {
|
||||
return registeredName;
|
||||
}
|
||||
|
||||
public String getProcedureName() {
|
||||
return procedureName;
|
||||
}
|
||||
|
||||
public ProcedureCallMemento toMemento(
|
||||
final SessionFactoryImpl sessionFactory,
|
||||
final Map<String,ResultSetMappingDefinition> resultSetMappingDefinitions) {
|
||||
final List<NativeSQLQueryReturn> collectedQueryReturns = new ArrayList<NativeSQLQueryReturn>();
|
||||
final Set<String> collectedQuerySpaces = new HashSet<String>();
|
||||
|
||||
final boolean specifiesResultClasses = resultClasses != null && resultClasses.length > 0;
|
||||
final boolean specifiesResultSetMappings = resultSetMappings != null && resultSetMappings.length > 0;
|
||||
|
||||
if ( specifiesResultClasses ) {
|
||||
Util.resolveResultClasses(
|
||||
new Util.ResultClassesResolutionContext() {
|
||||
@Override
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addQueryReturns(NativeSQLQueryReturn... queryReturns) {
|
||||
Collections.addAll( collectedQueryReturns, queryReturns );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addQuerySpaces(String... spaces) {
|
||||
Collections.addAll( collectedQuerySpaces, spaces );
|
||||
}
|
||||
},
|
||||
resultClasses
|
||||
);
|
||||
}
|
||||
else if ( specifiesResultSetMappings ) {
|
||||
Util.resolveResultSetMappings(
|
||||
new Util.ResultSetMappingResolutionContext() {
|
||||
@Override
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSetMappingDefinition findResultSetMapping(String name) {
|
||||
return resultSetMappingDefinitions.get( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addQueryReturns(NativeSQLQueryReturn... queryReturns) {
|
||||
Collections.addAll( collectedQueryReturns, queryReturns );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addQuerySpaces(String... spaces) {
|
||||
Collections.addAll( collectedQuerySpaces, spaces );
|
||||
}
|
||||
},
|
||||
resultSetMappings
|
||||
);
|
||||
}
|
||||
|
||||
return new ProcedureCallMementoImpl(
|
||||
procedureName,
|
||||
collectedQueryReturns.toArray( new NativeSQLQueryReturn[ collectedQueryReturns.size() ] ),
|
||||
parameterDefinitions.getParameterStrategy(),
|
||||
parameterDefinitions.toMementos( sessionFactory ),
|
||||
collectedQuerySpaces,
|
||||
hints
|
||||
);
|
||||
}
|
||||
|
||||
static class ParameterDefinitions {
|
||||
private final ParameterStrategy parameterStrategy;
|
||||
private final ParameterDefinition[] parameterDefinitions;
|
||||
|
||||
ParameterDefinitions(StoredProcedureParameter[] parameters) {
|
||||
if ( parameters == null || parameters.length == 0 ) {
|
||||
parameterStrategy = ParameterStrategy.POSITIONAL;
|
||||
parameterDefinitions = new ParameterDefinition[0];
|
||||
}
|
||||
else {
|
||||
parameterStrategy = StringHelper.isNotEmpty( parameters[0].name() )
|
||||
? ParameterStrategy.NAMED
|
||||
: ParameterStrategy.POSITIONAL;
|
||||
parameterDefinitions = new ParameterDefinition[ parameters.length ];
|
||||
for ( int i = 0; i < parameters.length; i++ ) {
|
||||
parameterDefinitions[i] = new ParameterDefinition( i, parameters[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ParameterStrategy getParameterStrategy() {
|
||||
return parameterStrategy;
|
||||
}
|
||||
|
||||
public List<ParameterMemento> toMementos(SessionFactoryImpl sessionFactory) {
|
||||
final List<ParameterMemento> mementos = new ArrayList<ParameterMemento>();
|
||||
for ( ParameterDefinition definition : parameterDefinitions ) {
|
||||
definition.toMemento( sessionFactory );
|
||||
}
|
||||
return mementos;
|
||||
}
|
||||
}
|
||||
|
||||
static class ParameterDefinition {
|
||||
private final Integer position;
|
||||
private final String name;
|
||||
private final ParameterMode parameterMode;
|
||||
private final Class type;
|
||||
|
||||
ParameterDefinition(int position, StoredProcedureParameter annotation) {
|
||||
this.position = position;
|
||||
this.name = normalize( annotation.name() );
|
||||
this.parameterMode = annotation.mode();
|
||||
this.type = annotation.type();
|
||||
}
|
||||
|
||||
public ParameterMemento toMemento(SessionFactoryImpl sessionFactory) {
|
||||
return new ParameterMemento(
|
||||
position,
|
||||
name,
|
||||
parameterMode,
|
||||
type,
|
||||
sessionFactory.getTypeResolver().heuristicType( type.getName() )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static String normalize(String name) {
|
||||
return StringHelper.isNotEmpty( name ) ? name : null;
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ import javax.persistence.NamedNativeQueries;
|
|||
import javax.persistence.NamedNativeQuery;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.NamedStoredProcedureQuery;
|
||||
import javax.persistence.QueryHint;
|
||||
import javax.persistence.SqlResultSetMapping;
|
||||
import javax.persistence.SqlResultSetMappings;
|
||||
|
@ -331,6 +332,20 @@ public abstract class QueryBinder {
|
|||
}
|
||||
}
|
||||
|
||||
public static void bindNamedStoredProcedureQuery(NamedStoredProcedureQuery annotation, Mappings mappings) {
|
||||
if ( annotation == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( BinderHelper.isEmptyAnnotationValue( annotation.name() ) ) {
|
||||
throw new AnnotationException( "A named query must have a name when used in class or package level" );
|
||||
}
|
||||
|
||||
final NamedProcedureCallDefinition def = new NamedProcedureCallDefinition( annotation );
|
||||
mappings.addNamedProcedureCallDefinition( def );
|
||||
LOG.debugf( "Bound named stored procedure query : %s => %s", def.getRegisteredName(), def.getProcedureName() );
|
||||
}
|
||||
|
||||
public static void bindSqlResultsetMappings(SqlResultSetMappings ann, Mappings mappings, boolean isDefault) {
|
||||
if ( ann == null ) return;
|
||||
for (SqlResultSetMapping rs : ann.value()) {
|
||||
|
|
|
@ -380,22 +380,31 @@ public class SessionDelegatorBaseImpl implements SessionImplementor, Session {
|
|||
|
||||
// Delegates to Session
|
||||
|
||||
@Override
|
||||
public Transaction beginTransaction() {
|
||||
return session.beginTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction getTransaction() {
|
||||
return session.getTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query createQuery(String queryString) {
|
||||
return session.createQuery( queryString );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLQuery createSQLQuery(String queryString) {
|
||||
return session.createSQLQuery( queryString );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureCall getNamedProcedureCall(String name) {
|
||||
return session.getNamedProcedureCall( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureCall createStoredProcedureCall(String procedureName) {
|
||||
return session.createStoredProcedureCall( procedureName );
|
||||
|
@ -411,298 +420,372 @@ public class SessionDelegatorBaseImpl implements SessionImplementor, Session {
|
|||
return session.createStoredProcedureCall( procedureName, resultSetMappings );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria createCriteria(Class persistentClass) {
|
||||
return session.createCriteria( persistentClass );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria createCriteria(Class persistentClass, String alias) {
|
||||
return session.createCriteria( persistentClass, alias );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria createCriteria(String entityName) {
|
||||
return session.createCriteria( entityName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria createCriteria(String entityName, String alias) {
|
||||
return session.createCriteria( entityName, alias );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SharedSessionBuilder sessionWithOptions() {
|
||||
return session.sessionWithOptions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactory getSessionFactory() {
|
||||
return session.getSessionFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection close() throws HibernateException {
|
||||
return session.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelQuery() throws HibernateException {
|
||||
session.cancelQuery();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirty() throws HibernateException {
|
||||
return session.isDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefaultReadOnly() {
|
||||
return session.isDefaultReadOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultReadOnly(boolean readOnly) {
|
||||
session.setDefaultReadOnly( readOnly );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable getIdentifier(Object object) {
|
||||
return session.getIdentifier( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object object) {
|
||||
return session.contains( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evict(Object object) {
|
||||
session.evict( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(Class theClass, Serializable id, LockMode lockMode) {
|
||||
return session.load( theClass, id, lockMode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(Class theClass, Serializable id, LockOptions lockOptions) {
|
||||
return session.load( theClass, id, lockOptions );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(String entityName, Serializable id, LockMode lockMode) {
|
||||
return session.load( entityName, id, lockMode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(String entityName, Serializable id, LockOptions lockOptions) {
|
||||
return session.load( entityName, id, lockOptions );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(Class theClass, Serializable id) {
|
||||
return session.load( theClass, id );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(String entityName, Serializable id) {
|
||||
return session.load( entityName, id );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(Object object, Serializable id) {
|
||||
session.load( object, id );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replicate(Object object, ReplicationMode replicationMode) {
|
||||
session.replicate( object, replicationMode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replicate(String entityName, Object object, ReplicationMode replicationMode) {
|
||||
session.replicate( entityName, object, replicationMode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable save(Object object) {
|
||||
return session.save( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable save(String entityName, Object object) {
|
||||
return session.save( entityName, object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveOrUpdate(Object object) {
|
||||
session.saveOrUpdate( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveOrUpdate(String entityName, Object object) {
|
||||
session.saveOrUpdate( entityName, object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Object object) {
|
||||
session.update( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(String entityName, Object object) {
|
||||
session.update( entityName, object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object merge(Object object) {
|
||||
return session.merge( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object merge(String entityName, Object object) {
|
||||
return session.merge( entityName, object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void persist(Object object) {
|
||||
session.persist( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void persist(String entityName, Object object) {
|
||||
session.persist( entityName, object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Object object) {
|
||||
session.delete( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String entityName, Object object) {
|
||||
session.delete( entityName, object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lock(Object object, LockMode lockMode) {
|
||||
session.lock( object, lockMode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lock(String entityName, Object object, LockMode lockMode) {
|
||||
session.lock( entityName, object, lockMode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockRequest buildLockRequest(LockOptions lockOptions) {
|
||||
return session.buildLockRequest( lockOptions );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(Object object) {
|
||||
session.refresh( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(String entityName, Object object) {
|
||||
session.refresh( entityName, object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(Object object, LockMode lockMode) {
|
||||
session.refresh( object, lockMode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(Object object, LockOptions lockOptions) {
|
||||
session.refresh( object, lockOptions );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(String entityName, Object object, LockOptions lockOptions) {
|
||||
session.refresh( entityName, object, lockOptions );
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockMode getCurrentLockMode(Object object) {
|
||||
return session.getCurrentLockMode( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query createFilter(Object collection, String queryString) {
|
||||
return session.createFilter( collection, queryString );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
session.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Class clazz, Serializable id) {
|
||||
return session.get( clazz, id );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Class clazz, Serializable id, LockMode lockMode) {
|
||||
return session.get( clazz, id, lockMode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Class clazz, Serializable id, LockOptions lockOptions) {
|
||||
return session.get( clazz, id, lockOptions );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String entityName, Serializable id) {
|
||||
return session.get( entityName, id );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String entityName, Serializable id, LockMode lockMode) {
|
||||
return session.get( entityName, id, lockMode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String entityName, Serializable id, LockOptions lockOptions) {
|
||||
return session.get( entityName, id, lockOptions );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEntityName(Object object) {
|
||||
return session.getEntityName( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifierLoadAccess byId(String entityName) {
|
||||
return session.byId( entityName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifierLoadAccess byId(Class entityClass) {
|
||||
return session.byId( entityClass );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NaturalIdLoadAccess byNaturalId(String entityName) {
|
||||
return session.byNaturalId( entityName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NaturalIdLoadAccess byNaturalId(Class entityClass) {
|
||||
return session.byNaturalId( entityClass );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleNaturalIdLoadAccess bySimpleNaturalId(String entityName) {
|
||||
return session.bySimpleNaturalId( entityName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleNaturalIdLoadAccess bySimpleNaturalId(Class entityClass) {
|
||||
return session.bySimpleNaturalId( entityClass );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter enableFilter(String filterName) {
|
||||
return session.enableFilter( filterName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getEnabledFilter(String filterName) {
|
||||
return session.getEnabledFilter( filterName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableFilter(String filterName) {
|
||||
session.disableFilter( filterName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionStatistics getStatistics() {
|
||||
return session.getStatistics();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly(Object entityOrProxy) {
|
||||
return session.isReadOnly( entityOrProxy );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadOnly(Object entityOrProxy, boolean readOnly) {
|
||||
session.setReadOnly( entityOrProxy, readOnly );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doWork(Work work) throws HibernateException {
|
||||
session.doWork( work );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T doReturningWork(ReturningWork<T> work) throws HibernateException {
|
||||
return session.doReturningWork( work );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection disconnect() {
|
||||
return session.disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnect(Connection connection) {
|
||||
session.reconnect( connection );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFetchProfileEnabled(String name) throws UnknownProfileException {
|
||||
return session.isFetchProfileEnabled( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableFetchProfile(String name) throws UnknownProfileException {
|
||||
session.enableFetchProfile( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableFetchProfile(String name) throws UnknownProfileException {
|
||||
session.disableFetchProfile( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeHelper getTypeHelper() {
|
||||
return session.getTypeHelper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LobHelper getLobHelper() {
|
||||
return session.getLobHelper();
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.hibernate.id.IdentifierGenerator;
|
|||
import org.hibernate.internal.NamedQueryRepository;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.procedure.ProcedureCallMemento;
|
||||
import org.hibernate.proxy.EntityNotFoundDelegate;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.io.Serializable;
|
|||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -59,6 +60,7 @@ import org.hibernate.jdbc.WorkExecutorVisitable;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
|
||||
import org.hibernate.procedure.ProcedureCallMemento;
|
||||
import org.hibernate.procedure.internal.ProcedureCallImpl;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
|
@ -67,11 +69,11 @@ import org.hibernate.type.Type;
|
|||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public abstract class AbstractSessionImpl implements Serializable, SharedSessionContract,
|
||||
SessionImplementor, TransactionContext {
|
||||
public abstract class AbstractSessionImpl
|
||||
implements Serializable, SharedSessionContract, SessionImplementor, TransactionContext {
|
||||
protected transient SessionFactoryImpl factory;
|
||||
private final String tenantIdentifier;
|
||||
private boolean closed = false;
|
||||
private boolean closed;
|
||||
|
||||
protected AbstractSessionImpl(SessionFactoryImpl factory, String tenantIdentifier) {
|
||||
this.factory = factory;
|
||||
|
@ -218,7 +220,7 @@ public abstract class AbstractSessionImpl implements Serializable, SharedSession
|
|||
@Override
|
||||
public Query createQuery(String queryString) {
|
||||
errorIfClosed();
|
||||
QueryImpl query = new QueryImpl(
|
||||
final QueryImpl query = new QueryImpl(
|
||||
queryString,
|
||||
this,
|
||||
getHQLQueryPlan( queryString, false ).getParameterMetadata()
|
||||
|
@ -230,7 +232,7 @@ public abstract class AbstractSessionImpl implements Serializable, SharedSession
|
|||
@Override
|
||||
public SQLQuery createSQLQuery(String sql) {
|
||||
errorIfClosed();
|
||||
SQLQueryImpl query = new SQLQueryImpl(
|
||||
final SQLQueryImpl query = new SQLQueryImpl(
|
||||
sql,
|
||||
this,
|
||||
factory.getQueryPlanCache().getSQLParameterMetadata( sql )
|
||||
|
@ -239,6 +241,22 @@ public abstract class AbstractSessionImpl implements Serializable, SharedSession
|
|||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
public ProcedureCall getNamedProcedureCall(String name) {
|
||||
errorIfClosed();
|
||||
|
||||
final ProcedureCallMemento memento = factory.getNamedQueryRepository().getNamedProcedureCallMemento( name );
|
||||
if ( memento == null ) {
|
||||
throw new IllegalArgumentException(
|
||||
"Could not find named stored procedure call with that registration name : " + name
|
||||
);
|
||||
}
|
||||
final ProcedureCall procedureCall = memento.makeProcedureCall( this );
|
||||
// procedureCall.setComment( "Named stored procedure call [" + name + "]" );
|
||||
return procedureCall;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
public ProcedureCall createStoredProcedureCall(String procedureName) {
|
||||
|
|
|
@ -25,20 +25,20 @@ package org.hibernate.internal;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.QueryException;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -46,14 +46,17 @@ import org.hibernate.internal.util.collections.CollectionHelper;
|
|||
public class NamedQueryRepository {
|
||||
private static final Logger log = Logger.getLogger( NamedQueryRepository.class );
|
||||
|
||||
private final Map<String, ResultSetMappingDefinition> namedSqlResultSetMappingMap;
|
||||
|
||||
private volatile Map<String, NamedQueryDefinition> namedQueryDefinitionMap;
|
||||
private volatile Map<String, NamedSQLQueryDefinition> namedSqlQueryDefinitionMap;
|
||||
private final Map<String, ResultSetMappingDefinition> namedSqlResultSetMappingMap;
|
||||
private volatile Map<String, ProcedureCallMemento> procedureCallMementoMap;
|
||||
|
||||
public NamedQueryRepository(
|
||||
Iterable<NamedQueryDefinition> namedQueryDefinitions,
|
||||
Iterable<NamedSQLQueryDefinition> namedSqlQueryDefinitions,
|
||||
Iterable<ResultSetMappingDefinition> namedSqlResultSetMappings) {
|
||||
Iterable<ResultSetMappingDefinition> namedSqlResultSetMappings,
|
||||
List<ProcedureCallMemento> namedProcedureCalls) {
|
||||
final HashMap<String, NamedQueryDefinition> namedQueryDefinitionMap = new HashMap<String, NamedQueryDefinition>();
|
||||
for ( NamedQueryDefinition namedQueryDefinition : namedQueryDefinitions ) {
|
||||
namedQueryDefinitionMap.put( namedQueryDefinition.getName(), namedQueryDefinition );
|
||||
|
@ -83,6 +86,10 @@ public class NamedQueryRepository {
|
|||
return namedSqlQueryDefinitionMap.get( queryName );
|
||||
}
|
||||
|
||||
public ProcedureCallMemento getNamedProcedureCallMemento(String name) {
|
||||
return procedureCallMementoMap.get( name );
|
||||
}
|
||||
|
||||
public ResultSetMappingDefinition getResultSetMappingDefinition(String mappingName) {
|
||||
return namedSqlResultSetMappingMap.get( mappingName );
|
||||
}
|
||||
|
@ -127,6 +134,20 @@ public class NamedQueryRepository {
|
|||
this.namedSqlQueryDefinitionMap = Collections.unmodifiableMap( copy );
|
||||
}
|
||||
|
||||
public synchronized void registerNamedProcedureCallMemento(String name, ProcedureCallMemento memento) {
|
||||
final Map<String, ProcedureCallMemento> 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<String,HibernateException> checkNamedQueries(QueryPlanCache queryPlanCache) {
|
||||
Map<String,HibernateException> errors = new HashMap<String,HibernateException>();
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
@ -82,6 +83,7 @@ import org.hibernate.cfg.Configuration;
|
|||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.cfg.Settings;
|
||||
import org.hibernate.cfg.SettingsFactory;
|
||||
import org.hibernate.cfg.annotations.NamedProcedureCallDefinition;
|
||||
import org.hibernate.context.internal.JTASessionContext;
|
||||
import org.hibernate.context.internal.ManagedSessionContext;
|
||||
import org.hibernate.context.internal.ThreadLocalSessionContext;
|
||||
|
@ -133,6 +135,7 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.persister.entity.Loadable;
|
||||
import org.hibernate.persister.entity.Queryable;
|
||||
import org.hibernate.persister.spi.PersisterFactory;
|
||||
import org.hibernate.procedure.ProcedureCallMemento;
|
||||
import org.hibernate.proxy.EntityNotFoundDelegate;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
|
@ -455,7 +458,8 @@ public final class SessionFactoryImpl
|
|||
this.namedQueryRepository = new NamedQueryRepository(
|
||||
cfg.getNamedQueries().values(),
|
||||
cfg.getNamedSQLQueries().values(),
|
||||
cfg.getSqlResultSetMappings().values()
|
||||
cfg.getSqlResultSetMappings().values(),
|
||||
toProcedureCallMementos( cfg.getNamedProcedureCallMap(), cfg.getSqlResultSetMappings() )
|
||||
);
|
||||
imports = new HashMap<String,String>( cfg.getImports() );
|
||||
|
||||
|
@ -576,6 +580,18 @@ public final class SessionFactoryImpl
|
|||
this.observer.sessionFactoryCreated( this );
|
||||
}
|
||||
|
||||
private List<ProcedureCallMemento> toProcedureCallMementos(
|
||||
Map<String, NamedProcedureCallDefinition> definitions,
|
||||
Map<String, ResultSetMappingDefinition> resultSetMappingMap) {
|
||||
final List<ProcedureCallMemento> rtn = new ArrayList<ProcedureCallMemento>();
|
||||
if ( definitions != null ) {
|
||||
for ( NamedProcedureCallDefinition definition : definitions.values() ) {
|
||||
rtn.add( definition.toMemento( this, resultSetMappingMap ) );
|
||||
}
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
private JdbcConnectionAccess buildLocalConnectionAccess() {
|
||||
return new JdbcConnectionAccess() {
|
||||
@Override
|
||||
|
@ -854,7 +870,8 @@ public final class SessionFactoryImpl
|
|||
namedQueryRepository = new NamedQueryRepository(
|
||||
metadata.getNamedQueryDefinitions(),
|
||||
metadata.getNamedNativeQueryDefinitions(),
|
||||
metadata.getResultSetMappingDefinitions()
|
||||
metadata.getResultSetMappingDefinitions(),
|
||||
null
|
||||
);
|
||||
|
||||
imports = new HashMap<String,String>();
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -131,6 +132,17 @@ public final class CollectionHelper {
|
|||
return new ArrayList<T>( anticipatedSize );
|
||||
}
|
||||
|
||||
public static <T> Set<T> makeCopy(Set<T> source) {
|
||||
if ( source == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int size = source.size();
|
||||
final Set<T> copy = new HashSet<T>( size + 1 );
|
||||
copy.addAll( source );
|
||||
return copy;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(Collection collection) {
|
||||
return collection == null || collection.isEmpty();
|
||||
}
|
||||
|
|
|
@ -24,7 +24,10 @@
|
|||
*/
|
||||
package org.hibernate.loader.custom.sql;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -56,9 +59,12 @@ import org.hibernate.loader.custom.NonScalarReturn;
|
|||
import org.hibernate.loader.custom.Return;
|
||||
import org.hibernate.loader.custom.RootReturn;
|
||||
import org.hibernate.loader.custom.ScalarReturn;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.collection.SQLLoadableCollection;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.Joinable;
|
||||
import org.hibernate.persister.entity.SQLLoadable;
|
||||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.EntityType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
|
@ -84,10 +90,10 @@ public class SQLQueryReturnProcessor {
|
|||
private final Map alias2Return = new HashMap();
|
||||
private final Map alias2OwnerAlias = new HashMap();
|
||||
|
||||
private final Map alias2Persister = new HashMap();
|
||||
private final Map<String,EntityPersister> alias2Persister = new HashMap<String,EntityPersister>();
|
||||
private final Map alias2Suffix = new HashMap();
|
||||
|
||||
private final Map alias2CollectionPersister = new HashMap();
|
||||
private final Map<String,CollectionPersister> alias2CollectionPersister = new HashMap<String,CollectionPersister>();
|
||||
private final Map alias2CollectionSuffix = new HashMap();
|
||||
|
||||
private final Map entityPropertyResultMaps = new HashMap();
|
||||
|
@ -112,7 +118,7 @@ public class SQLQueryReturnProcessor {
|
|||
this.factory = factory;
|
||||
}
|
||||
|
||||
/*package*/ class ResultAliasContext {
|
||||
public class ResultAliasContext {
|
||||
public SQLLoadable getEntityPersister(String alias) {
|
||||
return ( SQLLoadable ) alias2Persister.get( alias );
|
||||
}
|
||||
|
@ -136,6 +142,25 @@ public class SQLQueryReturnProcessor {
|
|||
public Map getPropertyResultsMap(String alias) {
|
||||
return internalGetPropertyResultsMap( alias );
|
||||
}
|
||||
|
||||
public String[] collectQuerySpaces() {
|
||||
final HashSet<String> spaces = new HashSet<String>();
|
||||
collectQuerySpaces( spaces );
|
||||
return spaces.toArray( new String[ spaces.size() ] );
|
||||
}
|
||||
|
||||
public void collectQuerySpaces(Collection<String> spaces) {
|
||||
for ( EntityPersister persister : alias2Persister.values() ) {
|
||||
Collections.addAll( spaces, (String[]) persister.getQuerySpaces() );
|
||||
}
|
||||
for ( CollectionPersister persister : alias2CollectionPersister.values() ) {
|
||||
final Type elementType = persister.getElementType();
|
||||
if ( elementType.isEntityType() && ! elementType.isAnyType() ) {
|
||||
final Joinable joinable = ( (EntityType) elementType ).getAssociatedJoinable( factory );
|
||||
Collections.addAll( spaces, (String[]) ( (EntityPersister) joinable ).getQuerySpaces() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map internalGetPropertyResultsMap(String alias) {
|
||||
|
|
|
@ -25,6 +25,7 @@ package org.hibernate.procedure;
|
|||
|
||||
import javax.persistence.ParameterMode;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.BasicQueryContract;
|
||||
import org.hibernate.MappingException;
|
||||
|
@ -58,6 +59,7 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
|
|||
* @param position The position
|
||||
* @param type The Java type of the parameter
|
||||
* @param mode The parameter mode (in, out, inout)
|
||||
* @param <T> The parameterized Java type of the parameter.
|
||||
*
|
||||
* @return The parameter registration memento
|
||||
*/
|
||||
|
@ -89,8 +91,12 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
|
|||
* @param parameterName The parameter name
|
||||
* @param type The Java type of the parameter
|
||||
* @param mode The parameter mode (in, out, inout)
|
||||
* @param <T> The parameterized Java type of the parameter.
|
||||
*
|
||||
* @return The parameter registration memento
|
||||
*
|
||||
* @throws NamedParametersNotSupportedException When the underlying database is known to not support
|
||||
* named procedure parameters.
|
||||
*/
|
||||
public <T> ParameterRegistration<T> registerParameter(String parameterName, Class<T> type, ParameterMode mode)
|
||||
throws NamedParametersNotSupportedException;
|
||||
|
@ -103,6 +109,9 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
|
|||
* @param mode The parameter mode (in, out, inout)
|
||||
*
|
||||
* @return The parameter registration memento
|
||||
*
|
||||
* @throws NamedParametersNotSupportedException When the underlying database is known to not support
|
||||
* named procedure parameters.
|
||||
*/
|
||||
public ProcedureCall registerParameter0(String parameterName, Class type, ParameterMode mode)
|
||||
throws NamedParametersNotSupportedException;
|
||||
|
@ -133,4 +142,12 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
|
|||
*/
|
||||
public ProcedureResult getResult();
|
||||
|
||||
/**
|
||||
* Extract the disconnected representation of this call. Used in HEM to allow redefining a named query
|
||||
*
|
||||
* @param hints The hints to incorporate into the memento
|
||||
*
|
||||
* @return The memento
|
||||
*/
|
||||
public ProcedureCallMemento extractMemento(Map<String, Object> hints);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
package org.hibernate.procedure;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
||||
/**
|
||||
* Represents a "memento" of a ProcedureCall
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ProcedureCallMemento {
|
||||
/**
|
||||
* Convert the memento back into an executable (connected) form.
|
||||
*
|
||||
* @param session The session to connect the procedure call to
|
||||
*
|
||||
* @return The executable call
|
||||
*/
|
||||
public ProcedureCall makeProcedureCall(Session session);
|
||||
|
||||
/**
|
||||
* Convert the memento back into an executable (connected) form.
|
||||
*
|
||||
* @param session The session to connect the procedure call to
|
||||
*
|
||||
* @return The executable call
|
||||
*/
|
||||
public ProcedureCall makeProcedureCall(SessionImplementor session);
|
||||
|
||||
/**
|
||||
* Access to any hints associated with the memento.
|
||||
* <p/>
|
||||
* IMPL NOTE : exposed separately because only HEM needs access to this.
|
||||
*
|
||||
* @return The hints.
|
||||
*/
|
||||
public Map<String, Object> getHintsMap();
|
||||
}
|
|
@ -43,6 +43,8 @@ import org.hibernate.type.ProcedureParameterExtractionAware;
|
|||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Abstract implementation of ParameterRegistration/ParameterRegistrationImplementor
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractParameterRegistrationImpl<T> implements ParameterRegistrationImplementor<T> {
|
||||
|
@ -62,28 +64,53 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
|
|||
private Type hibernateType;
|
||||
private int[] sqlTypes;
|
||||
|
||||
|
||||
// positional constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
protected AbstractParameterRegistrationImpl(
|
||||
ProcedureCallImpl procedureCall,
|
||||
Integer position,
|
||||
ParameterMode mode,
|
||||
Class<T> type) {
|
||||
this( procedureCall, position, null, mode, type );
|
||||
}
|
||||
|
||||
protected AbstractParameterRegistrationImpl(
|
||||
ProcedureCallImpl procedureCall,
|
||||
Integer position,
|
||||
ParameterMode mode,
|
||||
Class<T> type,
|
||||
ParameterMode mode) {
|
||||
this( procedureCall, position, null, type, mode );
|
||||
Type hibernateType) {
|
||||
this( procedureCall, position, null, mode, type, hibernateType );
|
||||
}
|
||||
|
||||
|
||||
// named constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
protected AbstractParameterRegistrationImpl(
|
||||
ProcedureCallImpl procedureCall,
|
||||
String name,
|
||||
ParameterMode mode,
|
||||
Class<T> type) {
|
||||
this( procedureCall, null, name, mode, type );
|
||||
}
|
||||
|
||||
protected AbstractParameterRegistrationImpl(
|
||||
ProcedureCallImpl procedureCall,
|
||||
String name,
|
||||
ParameterMode mode,
|
||||
Class<T> type,
|
||||
ParameterMode mode) {
|
||||
this( procedureCall, null, name, type, mode );
|
||||
Type hibernateType) {
|
||||
this( procedureCall, null, name, mode, type, hibernateType );
|
||||
}
|
||||
|
||||
private AbstractParameterRegistrationImpl(
|
||||
ProcedureCallImpl procedureCall,
|
||||
Integer position,
|
||||
String name,
|
||||
ParameterMode mode,
|
||||
Class<T> type,
|
||||
ParameterMode mode) {
|
||||
Type hibernateType) {
|
||||
this.procedureCall = procedureCall;
|
||||
|
||||
this.position = position;
|
||||
|
@ -92,7 +119,23 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
|
|||
this.mode = mode;
|
||||
this.type = type;
|
||||
|
||||
setHibernateType( session().getFactory().getTypeResolver().heuristicType( type.getName() ) );
|
||||
setHibernateType( hibernateType );
|
||||
}
|
||||
|
||||
private AbstractParameterRegistrationImpl(
|
||||
ProcedureCallImpl procedureCall,
|
||||
Integer position,
|
||||
String name,
|
||||
ParameterMode mode,
|
||||
Class<T> type) {
|
||||
this(
|
||||
procedureCall,
|
||||
position,
|
||||
name,
|
||||
mode,
|
||||
type,
|
||||
procedureCall.getSession().getFactory().getTypeResolver().heuristicType( type.getName() )
|
||||
);
|
||||
}
|
||||
|
||||
protected SessionImplementor session() {
|
||||
|
@ -119,6 +162,11 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
|
|||
return mode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getHibernateType() {
|
||||
return hibernateType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHibernateType(Type type) {
|
||||
if ( type == null ) {
|
||||
|
@ -129,6 +177,7 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public ParameterBind<T> getBind() {
|
||||
return bind;
|
||||
}
|
||||
|
@ -175,11 +224,12 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
|
|||
if ( mode == ParameterMode.IN || mode == ParameterMode.INOUT || mode == ParameterMode.OUT ) {
|
||||
if ( mode == ParameterMode.INOUT || mode == ParameterMode.OUT ) {
|
||||
if ( sqlTypes.length > 1 ) {
|
||||
if ( ProcedureParameterExtractionAware.class.isInstance( hibernateType )
|
||||
&& ( (ProcedureParameterExtractionAware) hibernateType ).canDoExtraction() ) {
|
||||
// the type can handle multi-param extraction...
|
||||
}
|
||||
else {
|
||||
// there is more than one column involved; see if the Hibernate Type can handle
|
||||
// multi-param extraction...
|
||||
final boolean canHandleMultiParamExtraction =
|
||||
ProcedureParameterExtractionAware.class.isInstance( hibernateType )
|
||||
&& ( (ProcedureParameterExtractionAware) hibernateType ).canDoExtraction();
|
||||
if ( ! canHandleMultiParamExtraction ) {
|
||||
// it cannot...
|
||||
throw new UnsupportedOperationException(
|
||||
"Type [" + hibernateType + "] does support multi-parameter value extraction"
|
||||
|
|
|
@ -25,15 +25,28 @@ package org.hibernate.procedure.internal;
|
|||
|
||||
import javax.persistence.ParameterMode;
|
||||
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Represents a registered named parameter
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NamedParameterRegistration<T> extends AbstractParameterRegistrationImpl<T> {
|
||||
public NamedParameterRegistration(
|
||||
NamedParameterRegistration(
|
||||
ProcedureCallImpl procedureCall,
|
||||
String name,
|
||||
ParameterMode mode,
|
||||
Class<T> type) {
|
||||
super( procedureCall, name, mode, type );
|
||||
}
|
||||
|
||||
NamedParameterRegistration(
|
||||
ProcedureCallImpl procedureCall,
|
||||
String name,
|
||||
ParameterMode mode,
|
||||
Class<T> type,
|
||||
ParameterMode mode) {
|
||||
super( procedureCall, name, type, mode );
|
||||
Type hibernateType) {
|
||||
super( procedureCall, name, mode, type, hibernateType );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,15 +27,45 @@ import java.sql.CallableStatement;
|
|||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.procedure.ParameterRegistration;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Additional internal contract for ParameterRegistration
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ParameterRegistrationImplementor<T> extends ParameterRegistration<T> {
|
||||
/**
|
||||
* Prepare for execution.
|
||||
*
|
||||
* @param statement The statement about to be executed
|
||||
* @param i The parameter index for this registration (used for positional)
|
||||
*
|
||||
* @throws SQLException Indicates a problem accessing the statement object
|
||||
*/
|
||||
public void prepare(CallableStatement statement, int i) throws SQLException;
|
||||
|
||||
/**
|
||||
* Access to the Hibernate type for this parameter registration
|
||||
*
|
||||
* @return The Hibernate Type
|
||||
*/
|
||||
public Type getHibernateType();
|
||||
|
||||
/**
|
||||
* Access to the SQL type(s) for this parameter
|
||||
*
|
||||
* @return The SQL types (JDBC type codes)
|
||||
*/
|
||||
public int[] getSqlTypes();
|
||||
|
||||
/**
|
||||
* Extract value from the statement after execution (used for OUT/INOUT parameters).
|
||||
*
|
||||
* @param statement The callable statement
|
||||
*
|
||||
* @return The extracted value
|
||||
*/
|
||||
public T extract(CallableStatement statement);
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,16 @@ package org.hibernate.procedure.internal;
|
|||
* The style/strategy of parameter registration used in a particular procedure call definition.
|
||||
*/
|
||||
public enum ParameterStrategy {
|
||||
/**
|
||||
* The parameters are named
|
||||
*/
|
||||
NAMED,
|
||||
/**
|
||||
* The parameters are positional
|
||||
*/
|
||||
POSITIONAL,
|
||||
/**
|
||||
* We do not (yet) know
|
||||
*/
|
||||
UNKNOWN
|
||||
}
|
||||
|
|
|
@ -25,15 +25,28 @@ package org.hibernate.procedure.internal;
|
|||
|
||||
import javax.persistence.ParameterMode;
|
||||
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Represents a registered positional parameter
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PositionalParameterRegistration<T> extends AbstractParameterRegistrationImpl<T> {
|
||||
public PositionalParameterRegistration(
|
||||
PositionalParameterRegistration(
|
||||
ProcedureCallImpl procedureCall,
|
||||
Integer position,
|
||||
ParameterMode mode,
|
||||
Class<T> type) {
|
||||
super( procedureCall, position, mode, type );
|
||||
}
|
||||
|
||||
PositionalParameterRegistration(
|
||||
ProcedureCallImpl procedureCall,
|
||||
Integer position,
|
||||
ParameterMode mode,
|
||||
Class<T> type,
|
||||
ParameterMode mode) {
|
||||
super( procedureCall, position, type, mode );
|
||||
Type hibernateType) {
|
||||
super( procedureCall, position, mode, type, hibernateType );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,25 +31,28 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.engine.ResultSetMappingDefinition;
|
||||
import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn;
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.internal.AbstractBasicQueryContractImpl;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.procedure.NamedParametersNotSupportedException;
|
||||
import org.hibernate.procedure.ParameterRegistration;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.procedure.ProcedureCallMemento;
|
||||
import org.hibernate.procedure.ProcedureResult;
|
||||
import org.hibernate.result.spi.ResultContext;
|
||||
import org.hibernate.type.Type;
|
||||
|
@ -60,6 +63,10 @@ import org.hibernate.type.Type;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements ProcedureCall, ResultContext {
|
||||
private static final Logger log = Logger.getLogger( ProcedureCallImpl.class );
|
||||
|
||||
private static final NativeSQLQueryReturn[] NO_RETURNS = new NativeSQLQueryReturn[0];
|
||||
|
||||
private final String procedureName;
|
||||
private final NativeSQLQueryReturn[] queryReturns;
|
||||
|
||||
|
@ -70,74 +77,167 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
|
|||
|
||||
private ProcedureResultImpl outputs;
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
/**
|
||||
* The no-returns form.
|
||||
*
|
||||
* @param session The session
|
||||
* @param procedureName The name of the procedure to call
|
||||
*/
|
||||
public ProcedureCallImpl(SessionImplementor session, String procedureName) {
|
||||
this( session, procedureName, (List) null );
|
||||
super( session );
|
||||
this.procedureName = procedureName;
|
||||
this.queryReturns = NO_RETURNS;
|
||||
}
|
||||
|
||||
public ProcedureCallImpl(SessionImplementor session, String procedureName, List<NativeSQLQueryReturn> queryReturns) {
|
||||
/**
|
||||
* The result Class(es) return form
|
||||
*
|
||||
* @param session The session
|
||||
* @param procedureName The name of the procedure to call
|
||||
* @param resultClasses The classes making up the result
|
||||
*/
|
||||
public ProcedureCallImpl(final SessionImplementor session, String procedureName, Class... resultClasses) {
|
||||
super( session );
|
||||
this.procedureName = procedureName;
|
||||
|
||||
if ( queryReturns == null || queryReturns.isEmpty() ) {
|
||||
this.queryReturns = new NativeSQLQueryReturn[0];
|
||||
final List<NativeSQLQueryReturn> collectedQueryReturns = new ArrayList<NativeSQLQueryReturn>();
|
||||
final Set<String> collectedQuerySpaces = new HashSet<String>();
|
||||
|
||||
Util.resolveResultClasses(
|
||||
new Util.ResultClassesResolutionContext() {
|
||||
@Override
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return session.getFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addQueryReturns(NativeSQLQueryReturn... queryReturns) {
|
||||
Collections.addAll( collectedQueryReturns, queryReturns );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addQuerySpaces(String... spaces) {
|
||||
Collections.addAll( collectedQuerySpaces, spaces );
|
||||
}
|
||||
},
|
||||
resultClasses
|
||||
);
|
||||
|
||||
this.queryReturns = collectedQueryReturns.toArray( new NativeSQLQueryReturn[ collectedQueryReturns.size() ] );
|
||||
this.synchronizedQuerySpaces = collectedQuerySpaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* The result-set-mapping(s) return form
|
||||
*
|
||||
* @param session The session
|
||||
* @param procedureName The name of the procedure to call
|
||||
* @param resultSetMappings The names of the result set mappings making up the result
|
||||
*/
|
||||
public ProcedureCallImpl(final SessionImplementor session, String procedureName, String... resultSetMappings) {
|
||||
super( session );
|
||||
this.procedureName = procedureName;
|
||||
|
||||
final List<NativeSQLQueryReturn> collectedQueryReturns = new ArrayList<NativeSQLQueryReturn>();
|
||||
final Set<String> collectedQuerySpaces = new HashSet<String>();
|
||||
|
||||
Util.resolveResultSetMappings(
|
||||
new Util.ResultSetMappingResolutionContext() {
|
||||
@Override
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return session.getFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSetMappingDefinition findResultSetMapping(String name) {
|
||||
return session.getFactory().getResultSetMapping( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addQueryReturns(NativeSQLQueryReturn... queryReturns) {
|
||||
Collections.addAll( collectedQueryReturns, queryReturns );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addQuerySpaces(String... spaces) {
|
||||
Collections.addAll( collectedQuerySpaces, spaces );
|
||||
}
|
||||
},
|
||||
resultSetMappings
|
||||
);
|
||||
|
||||
this.queryReturns = collectedQueryReturns.toArray( new NativeSQLQueryReturn[ collectedQueryReturns.size() ] );
|
||||
this.synchronizedQuerySpaces = collectedQuerySpaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* The named/stored copy constructor
|
||||
*
|
||||
* @param session The session
|
||||
* @param memento The named/stored memento
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
ProcedureCallImpl(SessionImplementor session, ProcedureCallMementoImpl memento) {
|
||||
super( session );
|
||||
this.procedureName = memento.getProcedureName();
|
||||
|
||||
this.queryReturns = memento.getQueryReturns();
|
||||
this.synchronizedQuerySpaces = Util.copy( memento.getSynchronizedQuerySpaces() );
|
||||
this.parameterStrategy = memento.getParameterStrategy();
|
||||
if ( parameterStrategy == ParameterStrategy.UNKNOWN ) {
|
||||
// nothing else to do in this case
|
||||
return;
|
||||
}
|
||||
|
||||
final List<ProcedureCallMementoImpl.ParameterMemento> storedRegistrations = memento.getParameterDeclarations();
|
||||
if ( storedRegistrations == null ) {
|
||||
// most likely a problem if ParameterStrategy is not UNKNOWN...
|
||||
log.debugf(
|
||||
"ParameterStrategy was [%s] on named copy [%s], but no parameters stored",
|
||||
parameterStrategy,
|
||||
procedureName
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final List<ParameterRegistrationImplementor<?>> parameterRegistrations =
|
||||
CollectionHelper.arrayList( storedRegistrations.size() );
|
||||
|
||||
for ( ProcedureCallMementoImpl.ParameterMemento storedRegistration : storedRegistrations ) {
|
||||
final ParameterRegistrationImplementor<?> registration;
|
||||
if ( StringHelper.isNotEmpty( storedRegistration.getName() ) ) {
|
||||
if ( parameterStrategy != ParameterStrategy.NAMED ) {
|
||||
throw new IllegalStateException(
|
||||
"Found named stored procedure parameter associated with positional parameters"
|
||||
);
|
||||
}
|
||||
registration = new NamedParameterRegistration(
|
||||
this,
|
||||
storedRegistration.getName(),
|
||||
storedRegistration.getMode(),
|
||||
storedRegistration.getType(),
|
||||
storedRegistration.getHibernateType()
|
||||
);
|
||||
}
|
||||
else {
|
||||
this.queryReturns = queryReturns.toArray( new NativeSQLQueryReturn[ queryReturns.size() ] );
|
||||
if ( parameterStrategy != ParameterStrategy.POSITIONAL ) {
|
||||
throw new IllegalStateException(
|
||||
"Found named stored procedure parameter associated with positional parameters"
|
||||
);
|
||||
}
|
||||
registration = new PositionalParameterRegistration(
|
||||
this,
|
||||
storedRegistration.getPosition(),
|
||||
storedRegistration.getMode(),
|
||||
storedRegistration.getType(),
|
||||
storedRegistration.getHibernateType()
|
||||
);
|
||||
}
|
||||
|
||||
public ProcedureCallImpl(SessionImplementor session, String procedureName, Class... resultClasses) {
|
||||
this( session, procedureName, collectQueryReturns( resultClasses ) );
|
||||
parameterRegistrations.add( registration );
|
||||
}
|
||||
|
||||
private static List<NativeSQLQueryReturn> collectQueryReturns(Class[] resultClasses) {
|
||||
if ( resultClasses == null || resultClasses.length == 0 ) {
|
||||
return null;
|
||||
this.registeredParameters = parameterRegistrations;
|
||||
}
|
||||
|
||||
List<NativeSQLQueryReturn> queryReturns = new ArrayList<NativeSQLQueryReturn>( resultClasses.length );
|
||||
int i = 1;
|
||||
for ( Class resultClass : resultClasses ) {
|
||||
queryReturns.add( new NativeSQLQueryRootReturn( "alias" + i, resultClass.getName(), LockMode.READ ) );
|
||||
i++;
|
||||
}
|
||||
return queryReturns;
|
||||
}
|
||||
|
||||
public ProcedureCallImpl(SessionImplementor session, String procedureName, String... resultSetMappings) {
|
||||
this( session, procedureName, collectQueryReturns( session, resultSetMappings ) );
|
||||
}
|
||||
|
||||
private static List<NativeSQLQueryReturn> collectQueryReturns(SessionImplementor session, String[] resultSetMappings) {
|
||||
if ( resultSetMappings == null || resultSetMappings.length == 0 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<NativeSQLQueryReturn> queryReturns = new ArrayList<NativeSQLQueryReturn>( resultSetMappings.length );
|
||||
for ( String resultSetMapping : resultSetMappings ) {
|
||||
ResultSetMappingDefinition mapping = session.getFactory().getResultSetMapping( resultSetMapping );
|
||||
if ( mapping == null ) {
|
||||
throw new MappingException( "Unknown SqlResultSetMapping [" + resultSetMapping + "]" );
|
||||
}
|
||||
queryReturns.addAll( Arrays.asList( mapping.getQueryReturns() ) );
|
||||
}
|
||||
return queryReturns;
|
||||
}
|
||||
|
||||
// public ProcedureCallImpl(
|
||||
// SessionImplementor session,
|
||||
// String procedureName,
|
||||
// List<StoredProcedureParameter> parameters) {
|
||||
// // this form is intended for named stored procedure calls.
|
||||
// // todo : introduce a NamedProcedureCallDefinition object to hold all needed info and pass that in here; will help with EM.addNamedQuery as well..
|
||||
// this( session, procedureName );
|
||||
// for ( StoredProcedureParameter parameter : parameters ) {
|
||||
// registerParameter( (StoredProcedureParameterImplementor) parameter );
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public SessionImplementor getSession() {
|
||||
return super.session();
|
||||
|
@ -165,7 +265,8 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
|
|||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> ParameterRegistration<T> registerParameter(int position, Class<T> type, ParameterMode mode) {
|
||||
final PositionalParameterRegistration parameterRegistration = new PositionalParameterRegistration( this, position, type, mode );
|
||||
final PositionalParameterRegistration parameterRegistration =
|
||||
new PositionalParameterRegistration( this, position, mode, type );
|
||||
registerParameter( parameterRegistration );
|
||||
return parameterRegistration;
|
||||
}
|
||||
|
@ -233,7 +334,8 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
|
|||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> ParameterRegistration<T> registerParameter(String name, Class<T> type, ParameterMode mode) {
|
||||
final NamedParameterRegistration parameterRegistration = new NamedParameterRegistration( this, name, type, mode );
|
||||
final NamedParameterRegistration parameterRegistration
|
||||
= new NamedParameterRegistration( this, name, mode, type );
|
||||
registerParameter( parameterRegistration );
|
||||
return parameterRegistration;
|
||||
}
|
||||
|
@ -329,6 +431,12 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
|
|||
throw new NotYetImplementedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this form instead of {@link #getSynchronizedQuerySpaces()} when you want to make sure the
|
||||
* underlying Set is instantiated (aka, on add)
|
||||
*
|
||||
* @return The spaces
|
||||
*/
|
||||
protected Set<String> synchronizedQuerySpaces() {
|
||||
if ( synchronizedQuerySpaces == null ) {
|
||||
synchronizedQuerySpaces = new HashSet<String>();
|
||||
|
@ -374,6 +482,7 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
|
|||
return buildQueryParametersObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryParameters buildQueryParametersObject() {
|
||||
QueryParameters qp = super.buildQueryParametersObject();
|
||||
// both of these are for documentation purposes, they are actually handled directly...
|
||||
|
@ -382,8 +491,13 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
|
|||
return qp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects any parameter registrations which indicate a REF_CURSOR parameter type/mode.
|
||||
*
|
||||
* @return The collected REF_CURSOR type parameters.
|
||||
*/
|
||||
public ParameterRegistrationImplementor[] collectRefCursorParameters() {
|
||||
List<ParameterRegistrationImplementor> refCursorParams = new ArrayList<ParameterRegistrationImplementor>();
|
||||
final List<ParameterRegistrationImplementor> refCursorParams = new ArrayList<ParameterRegistrationImplementor>();
|
||||
for ( ParameterRegistrationImplementor param : registeredParameters ) {
|
||||
if ( param.getMode() == ParameterMode.REF_CURSOR ) {
|
||||
refCursorParams.add( param );
|
||||
|
@ -391,4 +505,29 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
|
|||
}
|
||||
return refCursorParams.toArray( new ParameterRegistrationImplementor[refCursorParams.size()] );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureCallMemento extractMemento(Map<String, Object> hints) {
|
||||
return new ProcedureCallMementoImpl(
|
||||
procedureName,
|
||||
Util.copy( queryReturns ),
|
||||
parameterStrategy,
|
||||
toParameterMementos( registeredParameters ),
|
||||
Util.copy( synchronizedQuerySpaces ),
|
||||
Util.copy( hints )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private static List<ProcedureCallMementoImpl.ParameterMemento> toParameterMementos(List<ParameterRegistrationImplementor<?>> registeredParameters) {
|
||||
if ( registeredParameters == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<ProcedureCallMementoImpl.ParameterMemento> copy = CollectionHelper.arrayList( registeredParameters.size() );
|
||||
for ( ParameterRegistrationImplementor registration : registeredParameters ) {
|
||||
copy.add( ProcedureCallMementoImpl.ParameterMemento.fromRegistration( registration ) );
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
package org.hibernate.procedure.internal;
|
||||
|
||||
import javax.persistence.ParameterMode;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.procedure.ProcedureCallMemento;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Implementation of ProcedureCallMemento
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ProcedureCallMementoImpl implements ProcedureCallMemento {
|
||||
private final String procedureName;
|
||||
private final NativeSQLQueryReturn[] queryReturns;
|
||||
|
||||
private final ParameterStrategy parameterStrategy;
|
||||
private final List<ParameterMemento> parameterDeclarations;
|
||||
|
||||
private final Set<String> synchronizedQuerySpaces;
|
||||
|
||||
private final Map<String,Object> hintsMap;
|
||||
|
||||
public ProcedureCallMementoImpl(
|
||||
String procedureName,
|
||||
NativeSQLQueryReturn[] queryReturns,
|
||||
ParameterStrategy parameterStrategy,
|
||||
List<ParameterMemento> parameterDeclarations,
|
||||
Set<String> synchronizedQuerySpaces,
|
||||
Map<String,Object> hintsMap) {
|
||||
this.procedureName = procedureName;
|
||||
this.queryReturns = queryReturns;
|
||||
this.parameterStrategy = parameterStrategy;
|
||||
this.parameterDeclarations = parameterDeclarations;
|
||||
this.synchronizedQuerySpaces = synchronizedQuerySpaces;
|
||||
this.hintsMap = hintsMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureCall makeProcedureCall(Session session) {
|
||||
return new ProcedureCallImpl( (SessionImplementor) session, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureCall makeProcedureCall(SessionImplementor session) {
|
||||
return new ProcedureCallImpl( session, this );
|
||||
}
|
||||
|
||||
public String getProcedureName() {
|
||||
return procedureName;
|
||||
}
|
||||
|
||||
public NativeSQLQueryReturn[] getQueryReturns() {
|
||||
return queryReturns;
|
||||
}
|
||||
|
||||
public ParameterStrategy getParameterStrategy() {
|
||||
return parameterStrategy;
|
||||
}
|
||||
|
||||
public List<ParameterMemento> getParameterDeclarations() {
|
||||
return parameterDeclarations;
|
||||
}
|
||||
|
||||
public Set<String> getSynchronizedQuerySpaces() {
|
||||
return synchronizedQuerySpaces;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getHintsMap() {
|
||||
return hintsMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* A "disconnected" copy of the metadata for a parameter, that can be used in ProcedureCallMementoImpl.
|
||||
*/
|
||||
public static class ParameterMemento {
|
||||
private final Integer position;
|
||||
private final String name;
|
||||
private final ParameterMode mode;
|
||||
private final Class type;
|
||||
private final Type hibernateType;
|
||||
|
||||
/**
|
||||
* Create the memento
|
||||
*
|
||||
* @param position The parameter position
|
||||
* @param name The parameter name
|
||||
* @param mode The parameter mode
|
||||
* @param type The Java type of the parameter
|
||||
* @param hibernateType The Hibernate Type.
|
||||
*/
|
||||
public ParameterMemento(int position, String name, ParameterMode mode, Class type, Type hibernateType) {
|
||||
this.position = position;
|
||||
this.name = name;
|
||||
this.mode = mode;
|
||||
this.type = type;
|
||||
this.hibernateType = hibernateType;
|
||||
}
|
||||
|
||||
public Integer getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public ParameterMode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public Class getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Type getHibernateType() {
|
||||
return hibernateType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a ParameterMemento from the given parameter registration
|
||||
*
|
||||
* @param registration The parameter registration from a ProcedureCall
|
||||
*
|
||||
* @return The memento
|
||||
*/
|
||||
public static ParameterMemento fromRegistration(ParameterRegistrationImplementor registration) {
|
||||
return new ParameterMemento(
|
||||
registration.getPosition(),
|
||||
registration.getName(),
|
||||
registration.getMode(),
|
||||
registration.getType(),
|
||||
registration.getHibernateType()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
package org.hibernate.procedure.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.engine.ResultSetMappingDefinition;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.loader.custom.sql.SQLQueryReturnProcessor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class Util {
|
||||
private Util() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of the given query return array.
|
||||
*
|
||||
* @param queryReturns The returns to copy
|
||||
*
|
||||
* @return The copy
|
||||
*/
|
||||
static NativeSQLQueryReturn[] copy(NativeSQLQueryReturn[] queryReturns) {
|
||||
if ( queryReturns == null ) {
|
||||
return new NativeSQLQueryReturn[0];
|
||||
}
|
||||
|
||||
final NativeSQLQueryReturn[] copy = new NativeSQLQueryReturn[ queryReturns.length ];
|
||||
System.arraycopy( queryReturns, 0, copy, 0, queryReturns.length );
|
||||
return copy;
|
||||
}
|
||||
|
||||
public static Set<String> copy(Set<String> synchronizedQuerySpaces) {
|
||||
return CollectionHelper.makeCopy( synchronizedQuerySpaces );
|
||||
}
|
||||
|
||||
public static Map<String,Object> copy(Map<String, Object> hints) {
|
||||
return CollectionHelper.makeCopy( hints );
|
||||
}
|
||||
|
||||
public static interface ResultSetMappingResolutionContext {
|
||||
public SessionFactoryImplementor getSessionFactory();
|
||||
public ResultSetMappingDefinition findResultSetMapping(String name);
|
||||
public void addQueryReturns(NativeSQLQueryReturn... queryReturns);
|
||||
public void addQuerySpaces(String... spaces);
|
||||
}
|
||||
|
||||
public static void resolveResultSetMappings(ResultSetMappingResolutionContext context, String... resultSetMappingNames) {
|
||||
for ( String resultSetMappingName : resultSetMappingNames ) {
|
||||
final ResultSetMappingDefinition mapping = context.findResultSetMapping( resultSetMappingName );
|
||||
if ( mapping == null ) {
|
||||
throw new MappingException( "Unknown SqlResultSetMapping [" + resultSetMappingName + "]" );
|
||||
}
|
||||
|
||||
context.addQueryReturns( mapping.getQueryReturns() );
|
||||
|
||||
final SQLQueryReturnProcessor processor =
|
||||
new SQLQueryReturnProcessor( mapping.getQueryReturns(), context.getSessionFactory() );
|
||||
final SQLQueryReturnProcessor.ResultAliasContext processResult = processor.process();
|
||||
context.addQuerySpaces( processResult.collectQuerySpaces() );
|
||||
}
|
||||
}
|
||||
|
||||
public static interface ResultClassesResolutionContext {
|
||||
public SessionFactoryImplementor getSessionFactory();
|
||||
public void addQueryReturns(NativeSQLQueryReturn... queryReturns);
|
||||
public void addQuerySpaces(String... spaces);
|
||||
}
|
||||
|
||||
public static void resolveResultClasses(ResultClassesResolutionContext context, Class... resultClasses) {
|
||||
int i = 1;
|
||||
for ( Class resultClass : resultClasses ) {
|
||||
context.addQueryReturns(
|
||||
new NativeSQLQueryRootReturn( "alias" + i, resultClass.getName(), LockMode.READ )
|
||||
);
|
||||
try {
|
||||
final EntityPersister persister = context.getSessionFactory().getEntityPersister( resultClass.getName() );
|
||||
context.addQuerySpaces( (String[]) persister.getQuerySpaces() );
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -75,6 +75,7 @@ import org.hibernate.jpa.internal.metamodel.MetamodelImpl;
|
|||
import org.hibernate.jpa.internal.util.PersistenceUtilHelper;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.metadata.ClassMetadata;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
|
@ -284,19 +285,25 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
|
|||
throw new IllegalStateException( "EntityManagerFactory is closed" );
|
||||
}
|
||||
|
||||
if ( ! HibernateQuery.class.isInstance( query ) ) {
|
||||
if ( StoredProcedureQueryImpl.class.isInstance( query ) ) {
|
||||
final ProcedureCall procedureCall = ( (StoredProcedureQueryImpl) query ).getHibernateProcedureCall();
|
||||
sessionFactory.getNamedQueryRepository().registerNamedProcedureCallMemento( name, procedureCall.extractMemento( query.getHints() ) );
|
||||
}
|
||||
else if ( ! HibernateQuery.class.isInstance( query ) ) {
|
||||
throw new PersistenceException( "Cannot use query non-Hibernate EntityManager query as basis for named query" );
|
||||
}
|
||||
|
||||
else {
|
||||
// create and register the proper NamedQueryDefinition...
|
||||
final org.hibernate.Query hibernateQuery = ( (HibernateQuery) query ).getHibernateQuery();
|
||||
if ( org.hibernate.SQLQuery.class.isInstance( hibernateQuery ) ) {
|
||||
final NamedSQLQueryDefinition namedQueryDefinition = extractSqlQueryDefinition( ( org.hibernate.SQLQuery ) hibernateQuery, name );
|
||||
sessionFactory.registerNamedSQLQueryDefinition( name, namedQueryDefinition );
|
||||
sessionFactory.registerNamedSQLQueryDefinition(
|
||||
name,
|
||||
extractSqlQueryDefinition( (org.hibernate.SQLQuery) hibernateQuery, name )
|
||||
);
|
||||
}
|
||||
else {
|
||||
final NamedQueryDefinition namedQueryDefinition = extractHqlQueryDefinition( hibernateQuery, name );
|
||||
sessionFactory.registerNamedQueryDefinition( name, namedQueryDefinition );
|
||||
sessionFactory.registerNamedQueryDefinition( name, extractHqlQueryDefinition( hibernateQuery, name ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -298,6 +298,10 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
return false;
|
||||
}
|
||||
|
||||
public ProcedureCall getHibernateProcedureCall() {
|
||||
return procedureCall;
|
||||
}
|
||||
|
||||
private static class ParameterRegistrationImpl<T> implements ParameterRegistration<T> {
|
||||
private final org.hibernate.procedure.ParameterRegistration<T> nativeParamRegistration;
|
||||
|
||||
|
|
|
@ -124,6 +124,7 @@ import org.hibernate.jpa.internal.TransactionImpl;
|
|||
import org.hibernate.jpa.internal.util.CacheModeHelper;
|
||||
import org.hibernate.jpa.internal.util.ConfigurationHelper;
|
||||
import org.hibernate.jpa.internal.util.LockModeTypeHelper;
|
||||
import org.hibernate.procedure.ProcedureCallMemento;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.transform.BasicTransformerAdapter;
|
||||
|
@ -820,7 +821,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
public Query createNativeQuery(String sqlString, String resultSetMapping) {
|
||||
checkOpen();
|
||||
try {
|
||||
SQLQuery q = internalGetSession().createSQLQuery( sqlString );
|
||||
final SQLQuery q = internalGetSession().createSQLQuery( sqlString );
|
||||
q.setResultSetMapping( resultSetMapping );
|
||||
return new QueryImpl( q, this );
|
||||
}
|
||||
|
@ -832,15 +833,30 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
@Override
|
||||
public StoredProcedureQuery createNamedStoredProcedureQuery(String name) {
|
||||
checkOpen();
|
||||
throw new NotYetImplementedException();
|
||||
final ProcedureCallMemento memento = ( (SessionImplementor) internalGetSession() ).getFactory()
|
||||
.getNamedQueryRepository().getNamedProcedureCallMemento( name );
|
||||
if ( memento == null ) {
|
||||
throw new IllegalArgumentException( "No @NamedStoredProcedureQuery was found with that name : " + name );
|
||||
}
|
||||
final ProcedureCall procedureCall = memento.makeProcedureCall( internalGetSession() );
|
||||
final StoredProcedureQueryImpl jpaImpl = new StoredProcedureQueryImpl( procedureCall, this );
|
||||
// apply hints
|
||||
if ( memento.getHintsMap() != null ) {
|
||||
for ( Map.Entry<String,Object> hintEntry : memento.getHintsMap().entrySet() ) {
|
||||
jpaImpl.setHint( hintEntry.getKey(), hintEntry.getValue() );
|
||||
}
|
||||
}
|
||||
return jpaImpl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StoredProcedureQuery createStoredProcedureQuery(String procedureName) {
|
||||
checkOpen();
|
||||
try {
|
||||
ProcedureCall procedureCall = internalGetSession().createStoredProcedureCall( procedureName );
|
||||
return new StoredProcedureQueryImpl( procedureCall, this );
|
||||
return new StoredProcedureQueryImpl(
|
||||
internalGetSession().createStoredProcedureCall( procedureName ),
|
||||
this
|
||||
);
|
||||
}
|
||||
catch ( HibernateException he ) {
|
||||
throw convert( he );
|
||||
|
@ -851,8 +867,10 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses) {
|
||||
checkOpen();
|
||||
try {
|
||||
ProcedureCall procedureCall = internalGetSession().createStoredProcedureCall( procedureName, resultClasses );
|
||||
return new StoredProcedureQueryImpl( procedureCall, this );
|
||||
return new StoredProcedureQueryImpl(
|
||||
internalGetSession().createStoredProcedureCall( procedureName, resultClasses ),
|
||||
this
|
||||
);
|
||||
}
|
||||
catch ( HibernateException he ) {
|
||||
throw convert( he );
|
||||
|
@ -862,7 +880,15 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
@Override
|
||||
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings) {
|
||||
checkOpen();
|
||||
throw new NotYetImplementedException();
|
||||
try {
|
||||
return new StoredProcedureQueryImpl(
|
||||
internalGetSession().createStoredProcedureCall( procedureName, resultSetMappings ),
|
||||
this
|
||||
);
|
||||
}
|
||||
catch ( HibernateException he ) {
|
||||
throw convert( he );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue