From 5d09464c67ddf79276d3bdc9a7382f17f89575a4 Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Fri, 22 Nov 2013 16:22:36 -0800 Subject: [PATCH] HHH-8684 : Named output parameters don't work for stored procedure call --- .../hibernate/internal/CoreMessageLogger.java | 4 ++ .../procedure/internal/ProcedureCallImpl.java | 12 +++-- .../sql/storedproc/StoredProcedureTest.java | 50 +++++++++---------- 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java b/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java index d61f940ddc3e..cc1e04003db3 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java @@ -1662,4 +1662,8 @@ void cannotResolveNonNullableTransientDependencies(String transientEntityString, @Message(value = "The fetch attribute on has been deprecated. Instead of fetch=\"select\", use lazy=\"extra\" with , , , , or , which will only initialize entities (not as a proxy) as needed.", id = 455) void deprecatedManyToManyFetch(); + @LogMessage(level = WARN) + @Message(value = "Named parameters are used for a callable statement, but database metadata indicates named parameters are not supported.", id = 456) + void unsupportedNamedParameters(); + } diff --git a/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java b/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java index 848bd4661748..81de6d3016dc 100644 --- a/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java @@ -46,6 +46,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.internal.AbstractBasicQueryContractImpl; +import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.persister.entity.EntityPersister; @@ -67,7 +68,10 @@ * @author Steve Ebersole */ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements ProcedureCall, ResultContext { - private static final Logger log = Logger.getLogger( ProcedureCallImpl.class ); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + ProcedureCallImpl.class.getName() + ); private static final NativeSQLQueryReturn[] NO_RETURNS = new NativeSQLQueryReturn[0]; @@ -196,7 +200,7 @@ public void addQuerySpaces(String... spaces) { final List storedRegistrations = memento.getParameterDeclarations(); if ( storedRegistrations == null ) { // most likely a problem if ParameterStrategy is not UNKNOWN... - log.debugf( + LOG.debugf( "ParameterStrategy was [%s] on named copy [%s], but no parameters stored", parameterStrategy, procedureName @@ -314,9 +318,7 @@ private void prepareForNamedParameters() { .getJdbcServices() .getExtractedMetaDataSupport(); if ( ! databaseMetaData.supportsNamedParameters() ) { - throw new NamedParametersNotSupportedException( - "Named stored procedure parameters used, but JDBC driver does not support named parameters" - ); + LOG.unsupportedNamedParameters(); } parameterStrategy = ParameterStrategy.NAMED; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/sql/storedproc/StoredProcedureTest.java b/hibernate-core/src/test/java/org/hibernate/test/sql/storedproc/StoredProcedureTest.java index 64c11eac9a23..493879b6d4b5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/sql/storedproc/StoredProcedureTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/sql/storedproc/StoredProcedureTest.java @@ -235,31 +235,31 @@ else if ( id.equals( 3 ) ) { session.close(); } -// H2 does not support named parameters -// @Test -// public void testInParametersByName() { -// Session session = openSession(); -// session.beginTransaction(); -// -// ProcedureCall query = session.createStoredProcedureCall( "findUserRange" ); -// query.registerParameter( "start", Integer.class, ParameterMode.IN ).bindValue( 1 ); -// query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 ); -// ProcedureOutputs procedureResult = query.getOutputs(); -// Output currentOutput = procedureResult.getCurrent(); -// assertNotNull( currentOutput ); -// ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput ); -// List results = resultSetReturn.getResultList(); -// assertEquals( 1, results.size() ); -// Object result = results.get( 0 ); -// assertTyping( Object[].class, result ); -// Integer id = (Integer) ( (Object[]) result )[0]; -// String name = (String) ( (Object[]) result )[1]; -// assertEquals( 1, (int) id ); -// assertEquals( "User 1", name ); -// -// session.getTransaction().commit(); -// session.close(); -// } +// A warning should be logged if database metadata indicates named parameters are not supported. + @Test + public void testInParametersByName() { + Session session = openSession(); + session.beginTransaction(); + + ProcedureCall query = session.createStoredProcedureCall( "findUserRange" ); + query.registerParameter( "start", Integer.class, ParameterMode.IN ).bindValue( 1 ); + query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 ); + ProcedureOutputs procedureResult = query.getOutputs(); + Output currentOutput = procedureResult.getCurrent(); + assertNotNull( currentOutput ); + ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput ); + List results = resultSetReturn.getResultList(); + assertEquals( 1, results.size() ); + Object result = results.get( 0 ); + assertTyping( Object[].class, result ); + Integer id = (Integer) ( (Object[]) result )[0]; + String name = (String) ( (Object[]) result )[1]; + assertEquals( 1, (int) id ); + assertEquals( "User 1", name ); + + session.getTransaction().commit(); + session.close(); + } @Test public void testInParametersByPosition() {