Skip to content

Commit

Permalink
HHH-10515 - Add test for issue
Browse files Browse the repository at this point in the history
HHH-10515 - Fix Stored procedure execution fails to find column

HHH-10515 : Add test case using no JDBC DatabaseMetaData; move original test case to hibernate-core

HHH-10515 - Fix Stored procedure execution fails to find column
  • Loading branch information
dreab8 authored and gbadner committed Jun 14, 2016
1 parent dde7a5d commit 0eaf431
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 2 deletions.
11 changes: 11 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java
Expand Up @@ -2804,4 +2804,15 @@ public void augmentRecognizedTableTypes(List<String> tableTypesList) {
public boolean supportsPartitionBy() {
return false;
}

/**
* Override the DatabaseMetaData#supportsNamedParameters()
*
* @return boolean
*
* @throws SQLException Accessing the DatabaseMetaData can throw it. Just re-throw and Hibernate will handle.
*/
public boolean supportsNamedParameters(DatabaseMetaData databaseMetaData) throws SQLException {
return databaseMetaData != null && databaseMetaData.supportsNamedParameters();
}
}
Expand Up @@ -51,6 +51,7 @@
import org.hibernate.type.StandardBasicTypes;

import org.jboss.logging.Logger;
import java.sql.DatabaseMetaData;

/**
* An SQL dialect compatible with HSQLDB (HyperSQL).
Expand Down Expand Up @@ -669,4 +670,9 @@ public IdentityColumnSupport getIdentityColumnSupport() {
public NameQualifierSupport getNameQualifierSupport() {
return NameQualifierSupport.SCHEMA;
}

@Override
public boolean supportsNamedParameters(DatabaseMetaData databaseMetaData) throws SQLException {
return false;
}
}
Expand Up @@ -192,7 +192,6 @@ public Builder apply(DatabaseMetaData databaseMetaData) throws SQLException {
lobLocatorUpdateCopy = databaseMetaData.locatorsUpdateCopy();
typeInfoSet = new LinkedHashSet<TypeInfo>();
typeInfoSet.addAll( TypeInfo.extractTypeInfo( databaseMetaData ) );

return this;
}

Expand Down
Expand Up @@ -75,7 +75,6 @@ public JdbcEnvironmentImpl(ServiceRegistryImplementor serviceRegistry, Dialect d
this.nameQualifierSupport = nameQualifierSupport;

this.sqlExceptionHelper = buildSqlExceptionHelper( dialect, logWarnings( cfgService, dialect ) );
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this ).build();

final IdentifierHelperBuilder identifierHelperBuilder = IdentifierHelperBuilder.from( this );
identifierHelperBuilder.setGloballyQuoteIdentifiers( globalQuoting( cfgService ) );
Expand All @@ -84,8 +83,10 @@ public JdbcEnvironmentImpl(ServiceRegistryImplementor serviceRegistry, Dialect d
identifierHelperBuilder.setNameQualifierSupport( nameQualifierSupport );

IdentifierHelper identifierHelper = null;
ExtractedDatabaseMetaDataImpl.Builder dbMetaDataBuilder = new ExtractedDatabaseMetaDataImpl.Builder( this );
try {
identifierHelper = dialect.buildIdentifierHelper( identifierHelperBuilder, null );
dbMetaDataBuilder.setSupportsNamedParameters( dialect.supportsNamedParameters( null ) );
}
catch (SQLException sqle) {
// should never ever happen
Expand All @@ -96,6 +97,8 @@ public JdbcEnvironmentImpl(ServiceRegistryImplementor serviceRegistry, Dialect d
}
this.identifierHelper = identifierHelper;

this.extractedMetaDataSupport = dbMetaDataBuilder.build();

this.currentCatalog = identifierHelper.toIdentifier(
cfgService.getSetting( AvailableSettings.DEFAULT_CATALOG, StandardConverters.STRING )
);
Expand Down Expand Up @@ -152,6 +155,7 @@ public JdbcEnvironmentImpl(DatabaseMetaData databaseMetaData, Dialect dialect) t

this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this )
.apply( databaseMetaData )
.setSupportsNamedParameters( databaseMetaData.supportsNamedParameters() )
.build();

NameQualifierSupport nameQualifierSupport = dialect.getNameQualifierSupport();
Expand Down Expand Up @@ -226,6 +230,7 @@ public JdbcEnvironmentImpl(
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this )
.apply( databaseMetaData )
.setConnectionSchemaName( determineCurrentSchemaName( databaseMetaData, serviceRegistry, dialect ) )
.setSupportsNamedParameters(dialect.supportsNamedParameters(databaseMetaData))
.build();

NameQualifierSupport nameQualifierSupport = dialect.getNameQualifierSupport();
Expand Down
@@ -0,0 +1,141 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.jpa.test.procedure;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.ParameterMode;
import javax.persistence.StoredProcedureParameter;
import javax.persistence.StoredProcedureQuery;
import javax.persistence.Table;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import org.hibernate.dialect.HSQLDialect;
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;

import static org.junit.Assert.fail;

/**
* @author Andrea Boriero
*/
@TestForIssue(jiraKey = "HHH-10515")
@RequiresDialect(value = HSQLDialect.class)
public class HSQLStoreProcedureTest extends BaseEntityManagerFunctionalTestCase {
EntityManagerFactory entityManagerFactory;

@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] {User.class};
}

@Before
public void startUp() {
entityManagerFactory = getOrCreateEntityManager().getEntityManagerFactory();

createProcedures( entityManagerFactory );
}

@After
public void tearDown() {
dropProcedures( entityManagerFactory );
}

@Test
public void testNamedStoredProcedureExecution() {
EntityManager em = entityManagerFactory.createEntityManager();
try {
StoredProcedureQuery query = em.createNamedStoredProcedureQuery( "User.inoutproc" );
query.setParameter( "arg1", 1 );
query.execute();
}
finally {
em.close();
}
}

private void createProcedures(EntityManagerFactory emf) {
final String procedureStatement = "CREATE procedure inoutproc (IN arg1 int, OUT res int) " +
"BEGIN ATOMIC set res = arg1 + 1;" +
"END";
executeStatement( emf, procedureStatement );
}

private void dropProcedures(EntityManagerFactory emf) {
executeStatement( emf, "DROP procedure inoutproc" );
}

public void executeStatement(EntityManagerFactory emf, String toExecute) {
final SessionFactoryImplementor sf = emf.unwrap( SessionFactoryImplementor.class );
final JdbcConnectionAccess connectionAccess = sf.getServiceRegistry()
.getService( JdbcServices.class )
.getBootstrapJdbcConnectionAccess();
final Connection conn;
try {
conn = connectionAccess.obtainConnection();
conn.setAutoCommit( false );

try {
Statement statement = conn.createStatement();
statement.execute( toExecute );

try {
statement.close();
}
catch (SQLException e) {
fail( e.getMessage() );
}
}
finally {
try {
conn.commit();
}
catch (SQLException e) {
fail( e.getMessage() );
}

try {
connectionAccess.releaseConnection( conn );
}
catch (SQLException e) {
fail( e.getMessage() );
}
}
}
catch (SQLException e) {
throw new RuntimeException( "Unable to create stored procedures", e );
}
}

@Entity(name = "User")
@NamedStoredProcedureQuery(name = "User.inoutproc", procedureName = "inoutproc", parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "arg1", type = Integer.class),
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class)
})
@Table(name = "USERS")
public class User {

@Id
@GeneratedValue
private Integer id;
}
}
@@ -0,0 +1,91 @@
/**
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.jdbc.env;

import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;

import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

/**
* @author Gail Badner
*/
public class NoDatabaseMetaDataTest extends BaseUnitTestCase {

@Test
@TestForIssue( jiraKey = "HHH-10515" )
public void testNoJdbcMetadataDefaultDialect() {
final StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySetting( "hibernate.temp.use_jdbc_metadata_defaults", "false" )
.build();
JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
ExtractedDatabaseMetaData extractedDatabaseMetaData = jdbcEnvironment.getExtractedDatabaseMetaData();

assertNull( extractedDatabaseMetaData.getConnectionCatalogName() );
assertNull( extractedDatabaseMetaData.getConnectionSchemaName() );
assertTrue( extractedDatabaseMetaData.getTypeInfoSet().isEmpty() );
assertTrue( extractedDatabaseMetaData.getExtraKeywords().isEmpty() );
assertFalse( extractedDatabaseMetaData.supportsNamedParameters() );
assertFalse( extractedDatabaseMetaData.supportsRefCursors() );
assertFalse( extractedDatabaseMetaData.supportsScrollableResults() );
assertFalse( extractedDatabaseMetaData.supportsGetGeneratedKeys() );
assertFalse( extractedDatabaseMetaData.supportsBatchUpdates() );
assertFalse( extractedDatabaseMetaData.supportsDataDefinitionInTransaction() );
assertFalse( extractedDatabaseMetaData.doesDataDefinitionCauseTransactionCommit() );
assertNull( extractedDatabaseMetaData.getSqlStateType() );
assertFalse( extractedDatabaseMetaData.doesLobLocatorUpdateCopy() );

StandardServiceRegistryBuilder.destroy( serviceRegistry );
}

@Test
@TestForIssue( jiraKey = "HHH-10515" )
public void testNoJdbcMetadataDialectOverride() {
final StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySetting( "hibernate.temp.use_jdbc_metadata_defaults", "false" )
.applySetting( AvailableSettings.DIALECT, TestDialect.class.getName() )
.build();
JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
ExtractedDatabaseMetaData extractedDatabaseMetaData = jdbcEnvironment.getExtractedDatabaseMetaData();

assertNull( extractedDatabaseMetaData.getConnectionCatalogName() );
assertNull( extractedDatabaseMetaData.getConnectionSchemaName() );
assertTrue( extractedDatabaseMetaData.getTypeInfoSet().isEmpty() );
assertTrue( extractedDatabaseMetaData.getExtraKeywords().isEmpty() );
assertTrue( extractedDatabaseMetaData.supportsNamedParameters() );
assertFalse( extractedDatabaseMetaData.supportsRefCursors() );
assertFalse( extractedDatabaseMetaData.supportsScrollableResults() );
assertFalse( extractedDatabaseMetaData.supportsGetGeneratedKeys() );
assertFalse( extractedDatabaseMetaData.supportsBatchUpdates() );
assertFalse( extractedDatabaseMetaData.supportsDataDefinitionInTransaction() );
assertFalse( extractedDatabaseMetaData.doesDataDefinitionCauseTransactionCommit() );
assertNull( extractedDatabaseMetaData.getSqlStateType() );
assertFalse( extractedDatabaseMetaData.doesLobLocatorUpdateCopy() );

StandardServiceRegistryBuilder.destroy( serviceRegistry );
}

public static class TestDialect extends Dialect {
@Override
public boolean supportsNamedParameters(java.sql.DatabaseMetaData databaseMetaData) {
return true;
}
}

}

0 comments on commit 0eaf431

Please sign in to comment.