/*
* 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.sharedSession;
import org.hibernate.IrrelevantEntity;
import org.hibernate.Session;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PostInsertEvent;
import org.hibernate.event.spi.PostInsertEventListener;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
/**
* @author Steve Ebersole
*/
public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase {
@Test
@TestForIssue( jiraKey = "HHH-7090" )
public void testSharedTransactionContextSessionClosing() {
Session session = sessionFactory().openSession();
session.getTransaction().begin();
Session secondSession = session.sessionWithOptions()
.transactionContext()
.openSession();
secondSession.createCriteria( IrrelevantEntity.class ).list();
//the list should have registered and then released a JDBC resource
assertFalse(
((SessionImplementor) secondSession)
.getJdbcCoordinator()
.getResourceRegistry()
.hasRegisteredResources()
);
assertTrue( session.isOpen() );
assertTrue( secondSession.isOpen() );
assertSame( session.getTransaction(), secondSession.getTransaction() );
session.getTransaction().commit();
assertTrue( session.isOpen() );
assertTrue( secondSession.isOpen() );
secondSession.close();
assertTrue( session.isOpen() );
assertFalse( secondSession.isOpen() );
session.close();
assertFalse( session.isOpen() );
assertFalse( secondSession.isOpen() );
}
@Test
@TestForIssue( jiraKey = "HHH-7090" )
public void testSharedTransactionContextAutoClosing() {
Session session = sessionFactory().openSession();
session.getTransaction().begin();
// COMMIT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Session secondSession = session.sessionWithOptions()
.transactionContext()
.autoClose( true )
.openSession();
// directly assert state of the second session
assertTrue( ((SessionImplementor) secondSession).isAutoCloseSessionEnabled() );
assertTrue( ((SessionImplementor) secondSession).shouldAutoClose() );
// now commit the transaction and make sure that does not close the sessions
session.getTransaction().commit();
assertFalse( ((SessionImplementor) session).isClosed() );
assertTrue( ((SessionImplementor) secondSession).isClosed() );
session.close();
assertTrue( ((SessionImplementor) session).isClosed() );
assertTrue( ((SessionImplementor) secondSession).isClosed() );
// ROLLBACK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
session = sessionFactory().openSession();
session.getTransaction().begin();
secondSession = session.sessionWithOptions()
.transactionContext()
.autoClose( true )
.openSession();
// directly assert state of the second session
assertTrue( ((SessionImplementor) secondSession).isAutoCloseSessionEnabled() );
assertTrue( ((SessionImplementor) secondSession).shouldAutoClose() );
// now rollback the transaction and make sure that does not close the sessions
session.getTransaction().rollback();
assertFalse( ((SessionImplementor) session).isClosed() );
assertTrue( ((SessionImplementor) secondSession).isClosed() );
session.close();
assertTrue( ((SessionImplementor) session).isClosed() );
assertTrue( ((SessionImplementor) secondSession).isClosed() );
}
// @Test
// @TestForIssue( jiraKey = "HHH-7090" )
// public void testSharedTransactionContextAutoJoining() {
// Session session = sessionFactory().openSession();
// session.getTransaction().begin();
//
// Session secondSession = session.sessionWithOptions()
// .transactionContext()
// .autoJoinTransactions( true )
// .openSession();
//
// // directly assert state of the second session
// assertFalse( ((SessionImplementor) secondSession).shouldAutoJoinTransaction() );
//
// secondSession.close();
// session.close();
// }
@Test
@TestForIssue( jiraKey = "HHH-7090" )
public void testSharedTransactionContextFlushBeforeCompletion() {
Session session = sessionFactory().openSession();
session.getTransaction().begin();
Session secondSession = session.sessionWithOptions()
.transactionContext()
.flushBeforeCompletion( true )
.autoClose( true )
.openSession();
// directly assert state of the second session
// assertTrue( ((SessionImplementor) secondSession).isFlushBeforeCompletionEnabled() );
// now try it out
Integer id = (Integer) secondSession.save( new IrrelevantEntity() );
session.getTransaction().commit();
assertFalse( ((SessionImplementor) session).isClosed() );
assertTrue( ((SessionImplementor) secondSession).isClosed() );
session.close();
assertTrue( ((SessionImplementor) session).isClosed() );
assertTrue( ((SessionImplementor) secondSession).isClosed() );
session = sessionFactory().openSession();
session.getTransaction().begin();
IrrelevantEntity it = (IrrelevantEntity) session.byId( IrrelevantEntity.class ).load( id );
assertNotNull( it );
session.delete( it );
session.getTransaction().commit();
session.close();
}
@Test
@TestForIssue( jiraKey = "HHH-7239" )
public void testChildSessionCallsAfterTransactionAction() throws Exception {
Session session = openSession();
final String postCommitMessage = "post commit was called";
EventListenerRegistry eventListenerRegistry = sessionFactory().getServiceRegistry().getService(EventListenerRegistry.class);
//register a post commit listener
eventListenerRegistry.appendListeners(
EventType.POST_COMMIT_INSERT,
new PostInsertEventListener() {
@Override
public void onPostInsert(PostInsertEvent event) {
((IrrelevantEntity) event.getEntity()).setName( postCommitMessage );
}
@Override
public boolean requiresPostCommitHanding(EntityPersister persister) {
return true;
}
}
);
session.getTransaction().begin();
IrrelevantEntity irrelevantEntityMainSession = new IrrelevantEntity();
irrelevantEntityMainSession.setName( "main session" );
session.save( irrelevantEntityMainSession );
//open secondary session to also insert an entity
Session secondSession = session.sessionWithOptions()
.connection()
.flushBeforeCompletion( true )
.autoClose( true )
.openSession();
IrrelevantEntity irrelevantEntitySecondarySession = new IrrelevantEntity();
irrelevantEntitySecondarySession.setName( "secondary session" );
secondSession.save( irrelevantEntitySecondarySession );
session.getTransaction().commit();
//both entities should have their names updated to the postCommitMessage value
assertEquals(postCommitMessage, irrelevantEntityMainSession.getName());
assertEquals(postCommitMessage, irrelevantEntitySecondarySession.getName());
}
@Test
@TestForIssue( jiraKey = "HHH-7239" )
public void testChildSessionTwoTransactions() throws Exception {
Session session = openSession();
session.getTransaction().begin();
//open secondary session with managed options
Session secondarySession = session.sessionWithOptions()
.connection()
.flushBeforeCompletion( true )
.autoClose( true )
.openSession();
//the secondary session should be automatically closed after the commit
session.getTransaction().commit();
assertFalse( secondarySession.isOpen() );
//should be able to create a new transaction and carry on using the original session
session.getTransaction().begin();
session.getTransaction().commit();
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { IrrelevantEntity.class };
}
}