Revert "HHH-12391 - attempt to create test reproducing error; no luck"
This reverts commit 6e82e4fd53
.
This commit is contained in:
parent
6e82e4fd53
commit
7a47be8d9b
|
@ -6,30 +6,18 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.resource.transaction.jdbc.autocommit;
|
package org.hibernate.test.resource.transaction.jdbc.autocommit;
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.EntityTransaction;
|
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|
||||||
import org.hibernate.engine.transaction.spi.TransactionImplementor;
|
|
||||||
import org.hibernate.jpa.boot.spi.Bootstrap;
|
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
|
||||||
import org.hibernate.testing.transaction.TransactionUtil2;
|
|
||||||
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
|
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
|
@ -42,17 +30,10 @@ import static org.mockito.Mockito.verify;
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSkipAutoCommitTest extends BaseUnitTestCase {
|
public abstract class AbstractSkipAutoCommitTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
private PreparedStatementSpyConnectionProvider connectionProvider;
|
private PreparedStatementSpyConnectionProvider connectionProvider =
|
||||||
private DataSource dataSource;
|
new PreparedStatementSpyConnectionProvider() {
|
||||||
private SessionFactoryImplementor emf;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void createEntityManagerFactory() {
|
|
||||||
Map<String,Object> config = new HashMap<>();
|
|
||||||
|
|
||||||
connectionProvider = new PreparedStatementSpyConnectionProvider() {
|
|
||||||
@Override
|
@Override
|
||||||
protected Connection actualConnection() throws SQLException {
|
protected Connection actualConnection() throws SQLException {
|
||||||
Connection connection = super.actualConnection();
|
Connection connection = super.actualConnection();
|
||||||
|
@ -61,93 +42,51 @@ public abstract class AbstractSkipAutoCommitTest extends BaseUnitTestCase {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
dataSource = dataSource();
|
@Override
|
||||||
|
protected Map getConfig() {
|
||||||
|
Map config = super.getConfig();
|
||||||
|
|
||||||
config.put( AvailableSettings.CONNECTION_PROVIDER, connectionProvider );
|
config.put( AvailableSettings.DATASOURCE, dataSource() );
|
||||||
config.put( AvailableSettings.DATASOURCE, dataSource );
|
|
||||||
config.put( AvailableSettings.CONNECTION_PROVIDER_DISABLES_AUTOCOMMIT, Boolean.TRUE );
|
config.put( AvailableSettings.CONNECTION_PROVIDER_DISABLES_AUTOCOMMIT, Boolean.TRUE );
|
||||||
config.put( AvailableSettings.HBM2DDL_AUTO, "create-drop" );
|
config.put( AvailableSettings.CONNECTION_PROVIDER, connectionProvider );
|
||||||
|
|
||||||
config.put( AvailableSettings.JPA_TRANSACTION_COMPLIANCE, "false" );
|
return config;
|
||||||
|
|
||||||
emf = Bootstrap.getEntityManagerFactoryBuilder(
|
|
||||||
new BaseEntityManagerFunctionalTestCase.TestingPersistenceUnitDescriptorImpl( getClass().getSimpleName() ) {
|
|
||||||
@Override
|
|
||||||
public List<String> getManagedClassNames() {
|
|
||||||
return Collections.singletonList( City.class.getName() );
|
|
||||||
}
|
|
||||||
},
|
|
||||||
config
|
|
||||||
).build().unwrap( SessionFactoryImplementor.class );
|
|
||||||
if ( emf == null ) {
|
|
||||||
throw new RuntimeException( "Could not build EMF" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract DataSource dataSource();
|
protected abstract DataSource dataSource();
|
||||||
|
|
||||||
@After
|
@Override
|
||||||
public void releaseResources() {
|
public void releaseResources() {
|
||||||
if ( connectionProvider != null ) {
|
super.releaseResources();
|
||||||
connectionProvider.stop();
|
connectionProvider.stop();
|
||||||
}
|
|
||||||
|
|
||||||
// todo : somewhay to stop/close DataSource if not Closeable?
|
|
||||||
if ( dataSource instanceof Closeable ) {
|
|
||||||
try {
|
|
||||||
( (Closeable) dataSource ).close();
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
log.debugf( "Unable to release DataSource : %s", dataSource );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( emf != null ) {
|
|
||||||
emf.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Override
|
||||||
public void testRollbackOnNonJtaDataSourceWithAutoCommitConnection() {
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
TransactionUtil2.inEntityManager(
|
return new Class<?>[] {
|
||||||
emf,
|
City.class,
|
||||||
entityManager -> {
|
};
|
||||||
final EntityTransaction txn = entityManager.getTransaction();
|
|
||||||
// txn.begin();
|
|
||||||
|
|
||||||
final TransactionImplementor hibernateTxn = (TransactionImplementor) txn;
|
|
||||||
hibernateTxn.markRollbackOnly();
|
|
||||||
|
|
||||||
txn.rollback();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
connectionProvider.clear();
|
connectionProvider.clear();
|
||||||
doInJPA(
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
() -> emf,
|
City city = new City();
|
||||||
entityManager -> {
|
city.setId( 1L );
|
||||||
City city = new City();
|
city.setName( "Cluj-Napoca" );
|
||||||
city.setId( 1L );
|
entityManager.persist( city );
|
||||||
city.setName( "Cluj-Napoca" );
|
|
||||||
entityManager.persist( city );
|
|
||||||
|
|
||||||
assertTrue( connectionProvider.getAcquiredConnections().isEmpty() );
|
assertTrue( connectionProvider.getAcquiredConnections().isEmpty() );
|
||||||
assertTrue( connectionProvider.getReleasedConnections().isEmpty() );
|
assertTrue( connectionProvider.getReleasedConnections().isEmpty() );
|
||||||
}
|
} );
|
||||||
);
|
|
||||||
verifyConnections();
|
verifyConnections();
|
||||||
|
|
||||||
connectionProvider.clear();
|
connectionProvider.clear();
|
||||||
doInJPA(
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
() -> emf,
|
City city = entityManager.find( City.class, 1L );
|
||||||
entityManager -> {
|
assertEquals( "Cluj-Napoca", city.getName() );
|
||||||
City city = entityManager.find( City.class, 1L );
|
} );
|
||||||
assertEquals( "Cluj-Napoca", city.getName() );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
verifyConnections();
|
verifyConnections();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.Dialect;
|
|
||||||
import org.hibernate.dialect.MariaDBDialect;
|
import org.hibernate.dialect.MariaDBDialect;
|
||||||
import org.hibernate.dialect.MySQLDialect;
|
import org.hibernate.dialect.MySQLDialect;
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ public class MySQLSkipAutoCommitTest extends AbstractSkipAutoCommitTest {
|
||||||
@Override
|
@Override
|
||||||
protected DataSource dataSource() {
|
protected DataSource dataSource() {
|
||||||
DataSource dataSource = ReflectionUtil.newInstance( "com.mysql.cj.jdbc.MysqlDataSource" );
|
DataSource dataSource = ReflectionUtil.newInstance( "com.mysql.cj.jdbc.MysqlDataSource" );
|
||||||
if ( Dialect.getDialect() instanceof MariaDBDialect ) {
|
if ( getDialect() instanceof MariaDBDialect ) {
|
||||||
dataSource = ReflectionUtil.newInstance( "org.mariadb.jdbc.MariaDbDataSource" );
|
dataSource = ReflectionUtil.newInstance( "org.mariadb.jdbc.MariaDbDataSource" );
|
||||||
}
|
}
|
||||||
ReflectionUtil.setProperty( dataSource, "url", Environment.getProperties().getProperty( AvailableSettings.URL ) );
|
ReflectionUtil.setProperty( dataSource, "url", Environment.getProperties().getProperty( AvailableSettings.URL ) );
|
||||||
|
|
|
@ -7,9 +7,6 @@
|
||||||
package org.hibernate.testing.transaction;
|
package org.hibernate.testing.transaction;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
import javax.persistence.EntityTransaction;
|
|
||||||
|
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
@ -37,18 +34,6 @@ public class TransactionUtil2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void inEntityManager(EntityManagerFactory emf, Consumer<EntityManager> action) {
|
|
||||||
log.trace( "#inEntityManager(EMF,action)" );
|
|
||||||
|
|
||||||
try (SessionImplementor session = (SessionImplementor) emf.createEntityManager()) {
|
|
||||||
log.trace( "EntityManager opened, calling action" );
|
|
||||||
action.accept( session );
|
|
||||||
log.trace( "called action" );
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
log.trace( "EntityManager closed (AutoCloseable)" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void inTransaction(SessionFactoryImplementor factory, Consumer<SessionImplementor> action) {
|
public static void inTransaction(SessionFactoryImplementor factory, Consumer<SessionImplementor> action) {
|
||||||
log.trace( "#inTransaction(factory, action)");
|
log.trace( "#inTransaction(factory, action)");
|
||||||
|
@ -61,67 +46,6 @@ public class TransactionUtil2 {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void inEntityTransaction(EntityManagerFactory factory, Consumer<EntityManager> action) {
|
|
||||||
log.trace( "#inEntityTransaction(factory, action)");
|
|
||||||
|
|
||||||
inEntityManager(
|
|
||||||
factory,
|
|
||||||
session -> {
|
|
||||||
inEntityTransaction( session, action );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void inEntityTransaction(EntityManager entityManager, Consumer<EntityManager> action) {
|
|
||||||
log.trace( "#inTransaction(factory, action)");
|
|
||||||
|
|
||||||
final EntityTransaction txn = entityManager.getTransaction();
|
|
||||||
txn.begin();
|
|
||||||
log.trace( "Started transaction" );
|
|
||||||
|
|
||||||
try {
|
|
||||||
log.trace( "Calling action in txn" );
|
|
||||||
action.accept( entityManager );
|
|
||||||
log.trace( "Called action - in txn" );
|
|
||||||
|
|
||||||
if ( !txn.isActive() ) {
|
|
||||||
throw new TransactionManagementException( ACTION_COMPLETED_TXN );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
// an error happened in the action
|
|
||||||
if ( ! txn.isActive() ) {
|
|
||||||
log.warn( ACTION_COMPLETED_TXN, e );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.trace( "Rolling back transaction due to action error" );
|
|
||||||
try {
|
|
||||||
txn.rollback();
|
|
||||||
log.trace( "Rolled back transaction due to action error" );
|
|
||||||
}
|
|
||||||
catch (Exception inner) {
|
|
||||||
log.trace( "Rolling back transaction due to action error failed; throwing original error" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
// action completed with no errors - attempt to commit the transaction allowing
|
|
||||||
// any RollbackException to propagate. Note that when we get here we know the
|
|
||||||
// txn is active
|
|
||||||
|
|
||||||
log.trace( "Committing transaction after successful action execution" );
|
|
||||||
try {
|
|
||||||
txn.commit();
|
|
||||||
log.trace( "Committing transaction after successful action execution - success" );
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
log.trace( "Committing transaction after successful action execution - failure" );
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void inTransaction(SessionImplementor session, Consumer<SessionImplementor> action) {
|
public static void inTransaction(SessionImplementor session, Consumer<SessionImplementor> action) {
|
||||||
log.trace( "inTransaction(session,action)" );
|
log.trace( "inTransaction(session,action)" );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue