HHH-8400 - Positional parameters defined on NamedStoredProcedureQuery not applied
This commit is contained in:
parent
3102edba8b
commit
1a3a2a52a2
|
@ -33,6 +33,7 @@ dependencies {
|
||||||
testRuntime( 'jaxen:jaxen:1.1' )
|
testRuntime( 'jaxen:jaxen:1.1' )
|
||||||
testRuntime( libraries.javassist )
|
testRuntime( libraries.javassist )
|
||||||
testRuntime( libraries.unified_el )
|
testRuntime( libraries.unified_el )
|
||||||
|
testRuntime( libraries.derby ) // for testing stored procedure support
|
||||||
}
|
}
|
||||||
|
|
||||||
def pomName() {
|
def pomName() {
|
||||||
|
|
|
@ -173,7 +173,8 @@ public class NamedProcedureCallDefinition {
|
||||||
: ParameterStrategy.POSITIONAL;
|
: ParameterStrategy.POSITIONAL;
|
||||||
parameterDefinitions = new ParameterDefinition[ parameters.length ];
|
parameterDefinitions = new ParameterDefinition[ parameters.length ];
|
||||||
for ( int i = 0; i < parameters.length; i++ ) {
|
for ( int i = 0; i < parameters.length; i++ ) {
|
||||||
parameterDefinitions[i] = new ParameterDefinition( i, parameters[i] );
|
// i+1 for the position because the apis say the numbers are 1-based, not zero
|
||||||
|
parameterDefinitions[i] = new ParameterDefinition( i+1, parameters[i] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,12 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.hibernate.JDBCException;
|
import org.hibernate.JDBCException;
|
||||||
import org.hibernate.engine.spi.QueryParameters;
|
import org.hibernate.engine.spi.QueryParameters;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.loader.custom.CustomLoader;
|
import org.hibernate.loader.custom.CustomLoader;
|
||||||
import org.hibernate.loader.custom.CustomQuery;
|
import org.hibernate.loader.custom.CustomQuery;
|
||||||
import org.hibernate.loader.custom.sql.SQLQueryReturnProcessor;
|
import org.hibernate.loader.custom.sql.SQLQueryReturnProcessor;
|
||||||
|
@ -49,6 +52,8 @@ import org.hibernate.result.spi.ResultContext;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class ResultImpl implements Result {
|
public class ResultImpl implements Result {
|
||||||
|
private static final Logger log = CoreLogging.logger( ResultImpl.class );
|
||||||
|
|
||||||
private final ResultContext context;
|
private final ResultContext context;
|
||||||
private final PreparedStatement jdbcStatement;
|
private final PreparedStatement jdbcStatement;
|
||||||
private final CustomLoaderExtension loader;
|
private final CustomLoaderExtension loader;
|
||||||
|
@ -188,6 +193,15 @@ public class ResultImpl implements Result {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Return buildReturn() {
|
protected Return buildReturn() {
|
||||||
|
if ( log.isDebugEnabled() ) {
|
||||||
|
log.debugf(
|
||||||
|
"Building Return [isResultSet=%s, updateCount=%s, extendedReturn=%s",
|
||||||
|
isResultSet(),
|
||||||
|
getUpdateCount(),
|
||||||
|
hasExtendedReturns( currentReturnState )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if ( isResultSet() ) {
|
if ( isResultSet() ) {
|
||||||
return new ResultSetReturnImpl( extractCurrentResults() );
|
return new ResultSetReturnImpl( extractCurrentResults() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,9 @@ dependencies {
|
||||||
testRuntime( libraries.validator )
|
testRuntime( libraries.validator )
|
||||||
testRuntime( "org.jboss.spec.javax.ejb:jboss-ejb-api_3.2_spec:1.0.0.Alpha2" )
|
testRuntime( "org.jboss.spec.javax.ejb:jboss-ejb-api_3.2_spec:1.0.0.Alpha2" )
|
||||||
// testRuntime( "org.glassfish.web:el-impl:2.1.2-b04" )
|
// testRuntime( "org.glassfish.web:el-impl:2.1.2-b04" )
|
||||||
|
|
||||||
|
// for testing stored procedure support
|
||||||
|
testRuntime( libraries.derby )
|
||||||
}
|
}
|
||||||
|
|
||||||
def pomName() {
|
def pomName() {
|
||||||
|
|
|
@ -40,7 +40,9 @@ import java.util.List;
|
||||||
import org.hibernate.CacheMode;
|
import org.hibernate.CacheMode;
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.procedure.ParameterRegistration;
|
||||||
import org.hibernate.procedure.ProcedureCall;
|
import org.hibernate.procedure.ProcedureCall;
|
||||||
|
import org.hibernate.procedure.ProcedureCallMemento;
|
||||||
import org.hibernate.procedure.ProcedureResult;
|
import org.hibernate.procedure.ProcedureResult;
|
||||||
import org.hibernate.result.ResultSetReturn;
|
import org.hibernate.result.ResultSetReturn;
|
||||||
import org.hibernate.result.Return;
|
import org.hibernate.result.Return;
|
||||||
|
@ -60,6 +62,21 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
||||||
this.procedureCall = procedureCall;
|
this.procedureCall = procedureCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This form is used to build a StoredProcedureQueryImpl from a memento (usually from a NamedStoredProcedureQuery).
|
||||||
|
*
|
||||||
|
* @param memento The memento
|
||||||
|
* @param entityManager The EntityManager
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public StoredProcedureQueryImpl(ProcedureCallMemento memento, HibernateEntityManagerImplementor entityManager) {
|
||||||
|
super( entityManager );
|
||||||
|
this.procedureCall = memento.makeProcedureCall( entityManager.getSession() );
|
||||||
|
for ( org.hibernate.procedure.ParameterRegistration nativeParamReg : procedureCall.getRegisteredParameters() ) {
|
||||||
|
registerParameter( new ParameterRegistrationImpl( nativeParamReg ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean applyTimeoutHint(int timeout) {
|
protected boolean applyTimeoutHint(int timeout) {
|
||||||
procedureCall.setTimeout( timeout );
|
procedureCall.setTimeout( timeout );
|
||||||
|
|
|
@ -838,8 +838,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
||||||
if ( memento == null ) {
|
if ( memento == null ) {
|
||||||
throw new IllegalArgumentException( "No @NamedStoredProcedureQuery was found with that name : " + name );
|
throw new IllegalArgumentException( "No @NamedStoredProcedureQuery was found with that name : " + name );
|
||||||
}
|
}
|
||||||
final ProcedureCall procedureCall = memento.makeProcedureCall( internalGetSession() );
|
final StoredProcedureQueryImpl jpaImpl = new StoredProcedureQueryImpl( memento, this );
|
||||||
final StoredProcedureQueryImpl jpaImpl = new StoredProcedureQueryImpl( procedureCall, this );
|
|
||||||
// apply hints
|
// apply hints
|
||||||
if ( memento.getHintsMap() != null ) {
|
if ( memento.getHintsMap() != null ) {
|
||||||
for ( Map.Entry<String,Object> hintEntry : memento.getHintsMap().entrySet() ) {
|
for ( Map.Entry<String,Object> hintEntry : memento.getHintsMap().entrySet() ) {
|
||||||
|
|
|
@ -24,20 +24,38 @@
|
||||||
package org.hibernate.jpa.test.procedure;
|
package org.hibernate.jpa.test.procedure;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
import javax.persistence.StoredProcedureQuery;
|
import javax.persistence.StoredProcedureQuery;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.dialect.H2Dialect;
|
import org.h2.tools.SimpleResultSet;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.DerbyTenSevenDialect;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.jpa.AvailableSettings;
|
||||||
|
import org.hibernate.jpa.HibernateEntityManagerFactory;
|
||||||
|
import org.hibernate.jpa.boot.spi.Bootstrap;
|
||||||
|
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||||
|
import org.hibernate.jpa.internal.EntityManagerFactoryImpl;
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.hibernate.testing.FailureExpected;
|
import org.hibernate.testing.FailureExpected;
|
||||||
import org.hibernate.testing.RequiresDialect;
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
|
|
||||||
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
|
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
@ -48,29 +66,32 @@ import static org.junit.Assert.assertTrue;
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
@RequiresDialect( H2Dialect.class )
|
public class JpaTckUsageTest extends BaseUnitTestCase {
|
||||||
public class JpaTckUsageTest extends BaseEntityManagerFunctionalTestCase {
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMultipleGetUpdateCountCalls() {
|
public void testMultipleGetUpdateCountCalls() {
|
||||||
EntityManager em = getOrCreateEntityManager();
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
em.getTransaction().begin();
|
em.getTransaction().begin();
|
||||||
|
|
||||||
|
try {
|
||||||
StoredProcedureQuery query = em.createStoredProcedureQuery( "findOneUser" );
|
StoredProcedureQuery query = em.createStoredProcedureQuery( "findOneUser" );
|
||||||
// this is what the TCK attempts to do, don't shoot the messenger...
|
// this is what the TCK attempts to do, don't shoot the messenger...
|
||||||
query.getUpdateCount();
|
query.getUpdateCount();
|
||||||
// yep, twice
|
// yep, twice
|
||||||
query.getUpdateCount();
|
query.getUpdateCount();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicScalarResults() {
|
public void testBasicScalarResults() {
|
||||||
EntityManager em = getOrCreateEntityManager();
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
em.getTransaction().begin();
|
em.getTransaction().begin();
|
||||||
|
|
||||||
|
try {
|
||||||
StoredProcedureQuery query = em.createStoredProcedureQuery( "findOneUser" );
|
StoredProcedureQuery query = em.createStoredProcedureQuery( "findOneUser" );
|
||||||
boolean isResult = query.execute();
|
boolean isResult = query.execute();
|
||||||
assertTrue( isResult );
|
assertTrue( isResult );
|
||||||
|
@ -84,16 +105,19 @@ public class JpaTckUsageTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
results = query.hasMoreResults();
|
results = query.hasMoreResults();
|
||||||
// and it only sets the updateCount once lol
|
// and it only sets the updateCount once lol
|
||||||
} while ( results || updateCount != -1);
|
} while ( results || updateCount != -1);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testResultClassHandling() {
|
public void testResultClassHandling() {
|
||||||
EntityManager em = getOrCreateEntityManager();
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
em.getTransaction().begin();
|
em.getTransaction().begin();
|
||||||
|
|
||||||
|
try {
|
||||||
StoredProcedureQuery query = em.createStoredProcedureQuery( "findOneUser", User.class );
|
StoredProcedureQuery query = em.createStoredProcedureQuery( "findOneUser", User.class );
|
||||||
boolean isResult = query.execute();
|
boolean isResult = query.execute();
|
||||||
assertTrue( isResult );
|
assertTrue( isResult );
|
||||||
|
@ -108,48 +132,137 @@ public class JpaTckUsageTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
results = query.hasMoreResults();
|
results = query.hasMoreResults();
|
||||||
// and it only sets the updateCount once lol
|
// and it only sets the updateCount once lol
|
||||||
} while ( results || updateCount != -1);
|
} while ( results || updateCount != -1);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSettingInParamDefinedOnNamedStoredProcedureQuery() {
|
||||||
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
try {
|
||||||
|
StoredProcedureQuery query = em.createNamedStoredProcedureQuery( "positional-param" );
|
||||||
|
query.setParameter( 1, 1 );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Test
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
@FailureExpected( jiraKey = "HHH-8395", message = "Out of the frying pan into the fire: https://issues.apache.org/jira/browse/DERBY-211" )
|
||||||
return new Class[] { User.class };
|
public void testExecuteUpdate() {
|
||||||
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
|
||||||
|
try {
|
||||||
|
StoredProcedureQuery query = em.createStoredProcedureQuery( "deleteAllUsers" );
|
||||||
|
int count = query.executeUpdate();
|
||||||
|
// this fails because the Derby EmbeddedDriver is returning zero here rather than the actual updateCount :(
|
||||||
|
// https://issues.apache.org/jira/browse/DERBY-211
|
||||||
|
assertEquals( 1, count );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo : look at ways to allow "Auxiliary DB Objects" to the db via EMF bootstrapping.
|
// todo : look at ways to allow "Auxiliary DB Objects" to the db via EMF bootstrapping.
|
||||||
|
|
||||||
public static final String CREATE_CMD = "CREATE ALIAS findOneUser AS $$\n" +
|
// public static final String findOneUser_CREATE_CMD = "CREATE ALIAS findOneUser AS $$\n" +
|
||||||
"import org.h2.tools.SimpleResultSet;\n" +
|
// "import org.h2.tools.SimpleResultSet;\n" +
|
||||||
"import java.sql.*;\n" +
|
// "import java.sql.*;\n" +
|
||||||
"@CODE\n" +
|
// "@CODE\n" +
|
||||||
"ResultSet findOneUser() {\n" +
|
// "ResultSet findOneUser() {\n" +
|
||||||
" SimpleResultSet rs = new SimpleResultSet();\n" +
|
// " SimpleResultSet rs = new SimpleResultSet();\n" +
|
||||||
" rs.addColumn(\"ID\", Types.INTEGER, 10, 0);\n" +
|
// " rs.addColumn(\"ID\", Types.INTEGER, 10, 0);\n" +
|
||||||
" rs.addColumn(\"NAME\", Types.VARCHAR, 255, 0);\n" +
|
// " rs.addColumn(\"NAME\", Types.VARCHAR, 255, 0);\n" +
|
||||||
" rs.addRow(1, \"Steve\");\n" +
|
// " rs.addRow(1, \"Steve\");\n" +
|
||||||
" return rs;\n" +
|
// " return rs;\n" +
|
||||||
"}\n" +
|
// "}\n" +
|
||||||
"$$";
|
// "$$";
|
||||||
public static final String DROP_CMD = "DROP ALIAS findOneUser IF EXISTS";
|
// public static final String findOneUser_DROP_CMD = "DROP ALIAS findOneUser IF EXISTS";
|
||||||
|
//
|
||||||
|
// public static final String deleteAllUsers_CREATE_CMD = "CREATE ALIAS deleteAllUsers AS $$\n" +
|
||||||
|
// "@CODE\n" +
|
||||||
|
// "int deleteAllUsers() {\n" +
|
||||||
|
// " return 156;" +
|
||||||
|
// "}\n" +
|
||||||
|
// "$$";
|
||||||
|
// public static final String deleteAllUsers_DROP_CMD = "DROP ALIAS deleteAllUsers IF EXISTS";
|
||||||
|
|
||||||
@Override
|
HibernateEntityManagerFactory entityManagerFactory;
|
||||||
protected void afterEntityManagerFactoryBuilt() {
|
|
||||||
execute( CREATE_CMD );
|
@Before
|
||||||
|
public void startUp() {
|
||||||
|
// create the EMF
|
||||||
|
entityManagerFactory = (EntityManagerFactoryImpl) Bootstrap.getEntityManagerFactoryBuilder(
|
||||||
|
buildPersistenceUnitDescriptor(),
|
||||||
|
buildSettingsMap()
|
||||||
|
).build();
|
||||||
|
|
||||||
|
// create the procedures
|
||||||
|
createTestUser( entityManagerFactory );
|
||||||
|
createProcedures( entityManagerFactory );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void execute(String sql) {
|
private PersistenceUnitDescriptor buildPersistenceUnitDescriptor() {
|
||||||
System.out.println( "Executing SQL : " + sql );
|
return new BaseEntityManagerFunctionalTestCase.TestingPersistenceUnitDescriptorImpl( getClass().getSimpleName() );
|
||||||
final SessionFactoryImplementor sf = entityManagerFactory().unwrap( SessionFactoryImplementor.class );
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Map buildSettingsMap() {
|
||||||
|
Map settings = new HashMap();
|
||||||
|
|
||||||
|
settings.put( AvailableSettings.LOADED_CLASSES, Collections.singletonList( User.class ) );
|
||||||
|
|
||||||
|
settings.put( org.hibernate.cfg.AvailableSettings.DIALECT, DerbyTenSevenDialect.class );
|
||||||
|
settings.put( org.hibernate.cfg.AvailableSettings.DRIVER, org.apache.derby.jdbc.EmbeddedDriver.class.getName() );
|
||||||
|
settings.put( org.hibernate.cfg.AvailableSettings.URL, "jdbc:derby:hibernate-orm-testing;create=true" );
|
||||||
|
settings.put( org.hibernate.cfg.AvailableSettings.USER, "" );
|
||||||
|
|
||||||
|
settings.put( org.hibernate.cfg.AvailableSettings.HBM2DDL_AUTO, "create-drop" );
|
||||||
|
settings.put( org.hibernate.cfg.AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true" );
|
||||||
|
settings.put( org.hibernate.cfg.AvailableSettings.DIALECT, DerbyTenSevenDialect.class.getName() );
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
if ( entityManagerFactory == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteTestUser( entityManagerFactory );
|
||||||
|
dropProcedures( entityManagerFactory );
|
||||||
|
|
||||||
|
entityManagerFactory.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createProcedures(HibernateEntityManagerFactory emf) {
|
||||||
|
final SessionFactoryImplementor sf = emf.unwrap( SessionFactoryImplementor.class );
|
||||||
final Connection conn;
|
final Connection conn;
|
||||||
try {
|
try {
|
||||||
conn = sf.getConnectionProvider().getConnection();
|
conn = sf.getConnectionProvider().getConnection();
|
||||||
|
conn.setAutoCommit( false );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Statement statement = conn.createStatement();
|
Statement statement = conn.createStatement();
|
||||||
statement.execute( sql );
|
|
||||||
|
// drop them, just to be sure
|
||||||
|
try {
|
||||||
|
dropProcedures( statement );
|
||||||
|
}
|
||||||
|
catch (SQLException ignore) {
|
||||||
|
}
|
||||||
|
|
||||||
|
createProcedureFindOneUser( statement );
|
||||||
|
createProcedureDeleteAllUsers( statement );
|
||||||
try {
|
try {
|
||||||
statement.close();
|
statement.close();
|
||||||
}
|
}
|
||||||
|
@ -157,6 +270,13 @@ public class JpaTckUsageTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
try {
|
||||||
|
conn.commit();
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
System.out.println( "Unable to commit transaction after creating creating procedures");
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sf.getConnectionProvider().closeConnection( conn );
|
sf.getConnectionProvider().closeConnection( conn );
|
||||||
}
|
}
|
||||||
|
@ -165,13 +285,106 @@ public class JpaTckUsageTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException e) {
|
catch (SQLException e) {
|
||||||
throw new RuntimeException( "Unable to execute SQL : " + sql, e );
|
throw new RuntimeException( "Unable to create stored procedures", e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void dropProcedures(Statement statement) throws SQLException {
|
||||||
public void releaseResources() {
|
statement.execute( "DROP PROCEDURE findOneUser" );
|
||||||
execute( DROP_CMD );
|
statement.execute( "DROP PROCEDURE deleteAllUsers" );
|
||||||
super.releaseResources();
|
}
|
||||||
|
|
||||||
|
private void createProcedureFindOneUser(Statement statement) throws SQLException {
|
||||||
|
statement.execute(
|
||||||
|
"CREATE PROCEDURE findOneUser() " +
|
||||||
|
"language java " +
|
||||||
|
"dynamic result sets 1 " +
|
||||||
|
"external name 'org.hibernate.jpa.test.procedure.JpaTckUsageTest.findOneUser' " +
|
||||||
|
"parameter style java"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createProcedureDeleteAllUsers(Statement statement) throws SQLException {
|
||||||
|
statement.execute(
|
||||||
|
"CREATE PROCEDURE deleteAllUsers() " +
|
||||||
|
"language java " +
|
||||||
|
"external name 'org.hibernate.jpa.test.procedure.JpaTckUsageTest.deleteAllUsers' " +
|
||||||
|
"parameter style java"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void findOneUser(ResultSet[] results) throws SQLException {
|
||||||
|
Connection conn = DriverManager.getConnection( "jdbc:default:connection" );
|
||||||
|
PreparedStatement ps = conn.prepareStatement( "select id, name from t_user where name=?" );
|
||||||
|
ps.setString( 1, "steve" );
|
||||||
|
results[0] = ps.executeQuery();
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deleteAllUsers() throws SQLException {
|
||||||
|
// afaict the only way to return update counts here is to actually perform some DML
|
||||||
|
Connection conn = DriverManager.getConnection( "jdbc:default:connection" );
|
||||||
|
System.out.println( "Preparing delete all" );
|
||||||
|
PreparedStatement ps = conn.prepareStatement( "delete from t_user" );
|
||||||
|
System.out.println( "Executing delete all" );
|
||||||
|
int count = ps.executeUpdate();
|
||||||
|
System.out.println( "Count : " + count );
|
||||||
|
System.out.println( "Closing resources" );
|
||||||
|
ps.close();
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTestUser(HibernateEntityManagerFactory entityManagerFactory) {
|
||||||
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
|
||||||
|
em.persist( new User( 1, "steve" ) );
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteTestUser(HibernateEntityManagerFactory entityManagerFactory) {
|
||||||
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.createQuery( "delete from User" ).executeUpdate();
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dropProcedures(HibernateEntityManagerFactory emf) {
|
||||||
|
|
||||||
|
final SessionFactoryImplementor sf = emf.unwrap( SessionFactoryImplementor.class );
|
||||||
|
final Connection conn;
|
||||||
|
try {
|
||||||
|
conn = sf.getConnectionProvider().getConnection();
|
||||||
|
conn.setAutoCommit( false );
|
||||||
|
|
||||||
|
try {
|
||||||
|
Statement statement = conn.createStatement();
|
||||||
|
dropProcedures( statement );
|
||||||
|
try {
|
||||||
|
statement.close();
|
||||||
|
}
|
||||||
|
catch (SQLException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
conn.commit();
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
System.out.println( "Unable to commit transaction after creating dropping procedures");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
sf.getConnectionProvider().closeConnection( conn );
|
||||||
|
}
|
||||||
|
catch (SQLException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
throw new RuntimeException( "Unable to drop stored procedures", e );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import javax.persistence.NamedStoredProcedureQuery;
|
||||||
import javax.persistence.ParameterMode;
|
import javax.persistence.ParameterMode;
|
||||||
import javax.persistence.SqlResultSetMapping;
|
import javax.persistence.SqlResultSetMapping;
|
||||||
import javax.persistence.StoredProcedureParameter;
|
import javax.persistence.StoredProcedureParameter;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Strong Liu <stliu@hibernate.org>
|
* @author Strong Liu <stliu@hibernate.org>
|
||||||
|
@ -43,6 +44,13 @@ import javax.persistence.StoredProcedureParameter;
|
||||||
},
|
},
|
||||||
resultSetMappings = { "srms" }
|
resultSetMappings = { "srms" }
|
||||||
|
|
||||||
|
),
|
||||||
|
@NamedStoredProcedureQuery(
|
||||||
|
name = "positional-param",
|
||||||
|
procedureName = "positionalParameterTesting",
|
||||||
|
parameters = {
|
||||||
|
@StoredProcedureParameter( mode = ParameterMode.IN, type = Integer.class )
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -54,11 +62,20 @@ import javax.persistence.StoredProcedureParameter;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@Table( name = "T_USER" )
|
||||||
public class User {
|
public class User {
|
||||||
@Id
|
@Id
|
||||||
private int id;
|
private int id;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(int id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,15 @@
|
||||||
# 51 Franklin Street, Fifth Floor
|
# 51 Franklin Street, Fifth Floor
|
||||||
# Boston, MA 02110-1301 USA
|
# Boston, MA 02110-1301 USA
|
||||||
#
|
#
|
||||||
hibernate.dialect org.hibernate.dialect.H2Dialect
|
|
||||||
hibernate.connection.driver_class org.h2.Driver
|
#hibernate.dialect org.hibernate.dialect.H2Dialect
|
||||||
hibernate.connection.url jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE;LOCK_TIMEOUT=10000
|
#hibernate.connection.driver_class org.h2.Driver
|
||||||
|
#hibernate.connection.url jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE;LOCK_TIMEOUT=10000
|
||||||
|
#hibernate.connection.username sa
|
||||||
|
|
||||||
|
hibernate.dialect org.hibernate.dialect.DerbyTenSevenDialect
|
||||||
|
hibernate.connection.driver_class org.apache.derby.jdbc.EmbeddedDriver
|
||||||
|
hibernate.connection.url jdbc:derby:memory:hibernate-orm-testing;create=true
|
||||||
hibernate.connection.username sa
|
hibernate.connection.username sa
|
||||||
|
|
||||||
hibernate.connection.pool_size 5
|
hibernate.connection.pool_size 5
|
||||||
|
|
|
@ -92,6 +92,7 @@ ext {
|
||||||
shrinkwrap: 'org.jboss.shrinkwrap:shrinkwrap-impl-base:1.0.0-beta-6',
|
shrinkwrap: 'org.jboss.shrinkwrap:shrinkwrap-impl-base:1.0.0-beta-6',
|
||||||
validator: 'org.hibernate:hibernate-validator:5.0.1.Final',
|
validator: 'org.hibernate:hibernate-validator:5.0.1.Final',
|
||||||
h2: "com.h2database:h2:${h2Version}",
|
h2: "com.h2database:h2:${h2Version}",
|
||||||
|
derby: "org.apache.derby:derby:10.9.1.0",
|
||||||
jboss_jta: "org.jboss.jbossts:jbossjta:4.16.4.Final",
|
jboss_jta: "org.jboss.jbossts:jbossjta:4.16.4.Final",
|
||||||
xapool: "com.experlog:xapool:1.5.0",
|
xapool: "com.experlog:xapool:1.5.0",
|
||||||
mockito: 'org.mockito:mockito-core:1.9.0',
|
mockito: 'org.mockito:mockito-core:1.9.0',
|
||||||
|
|
Loading…
Reference in New Issue