Skip to content

Commit

Permalink
HHH-11067 - Proxy-wrapped Sessions (ThreadLocalSessionContext.Transac…
Browse files Browse the repository at this point in the history
…tionProtectionWrapper) handle equals incorrectly
  • Loading branch information
sebersole committed Aug 26, 2016
1 parent 4f991c3 commit aaa32eb
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.transaction.Synchronization;

Expand Down Expand Up @@ -291,17 +292,33 @@ public TransactionProtectionWrapper(Session realSession) {
}

@Override
@SuppressWarnings("SimplifiableIfStatement")
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final String methodName = method.getName();
final String methodName = method.getName();

// first check methods calls that we handle completely locally:
if ( "equals".equals( methodName ) && method.getParameterCount() == 1 ) {
if ( args[0] == null
|| !Proxy.isProxyClass( args[0].getClass() ) ) {
return false;
}
return this.equals( Proxy.getInvocationHandler( args[0] ) );
}
else if ( "hashCode".equals( methodName ) && method.getParameterCount() == 0 ) {
return this.hashCode();
}
else if ( "toString".equals( methodName ) && method.getParameterCount() == 0 ) {
return String.format( Locale.ROOT, "ThreadLocalSessionContext.TransactionProtectionWrapper[%s]", realSession );
}


// then check method calls that we need to delegate to the real Session
try {
// If close() is called, guarantee unbind()
if ( "close".equals( methodName ) ) {
unbind( realSession.getSessionFactory() );
}
else if ( "toString".equals( methodName )
|| "equals".equals( methodName )
|| "hashCode".equals( methodName )
|| "getStatistics".equals( methodName )
else if ( "getStatistics".equals( methodName )
|| "isOpen".equals( methodName )
|| "getListeners".equals( methodName ) ) {
// allow these to go through the the real session no matter what
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
import org.hibernate.resource.transaction.spi.TransactionStatus;

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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

Expand Down Expand Up @@ -73,12 +75,22 @@ protected void checkDeserializedState(Session session) {
assertTrue( "session not bound afterQuery deserialize", TestableThreadLocalContext.isSessionBound( session ) );
}

@Test
@TestForIssue(jiraKey = "HHH-11067")
public void testEqualityChecking() {
Session session1 = sessionFactory().getCurrentSession();
Session session2 = sessionFactory().getCurrentSession();

assertSame( "== check", session1, session2 );
assertEquals( "#equals check", session1, session2 );
}

@Test
public void testTransactionProtection() {
Session session = sessionFactory().getCurrentSession();
try {
session.createQuery( "from Silly" );
fail( "method other than beginTransaction{} allowed" );
fail( "method other than beginTransaction() allowed" );
}
catch ( HibernateException e ) {
// ok
Expand Down

0 comments on commit aaa32eb

Please sign in to comment.