diff --git a/hibernate-core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java b/hibernate-core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java index 4585e0088e..113ca45bf3 100644 --- a/hibernate-core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java +++ b/hibernate-core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java @@ -72,11 +72,12 @@ public class ThreadLocalSessionContext implements CurrentSessionContext { private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, ThreadLocalSessionContext.class.getName()); - private static final Class[] SESS_PROXY_INTERFACES = new Class[] { + private static final Class[] SESSION_PROXY_INTERFACES = new Class[] { org.hibernate.classic.Session.class, org.hibernate.engine.SessionImplementor.class, org.hibernate.engine.jdbc.spi.JDBCContext.Context.class, - org.hibernate.event.EventSource.class + org.hibernate.event.EventSource.class, + org.hibernate.engine.jdbc.LobCreationContext.class }; /** @@ -85,7 +86,7 @@ public class ThreadLocalSessionContext implements CurrentSessionContext { * the possibility for multiple SessionFactorys being used during execution * of the given thread. */ - private static final ThreadLocal context = new ThreadLocal(); + private static final ThreadLocal context = new ThreadLocal(); protected final SessionFactoryImplementor factory; @@ -100,7 +101,7 @@ public class ThreadLocalSessionContext implements CurrentSessionContext { Session current = existingSession( factory ); if (current == null) { current = buildOrObtainSession(); - // register a cleanup synch + // register a cleanup sync current.getTransaction().registerSynchronization( buildCleanupSynch() ); // wrap the session in the transaction-protection proxy if ( needsWrapping( current ) ) { @@ -181,7 +182,7 @@ public class ThreadLocalSessionContext implements CurrentSessionContext { TransactionProtectionWrapper wrapper = new TransactionProtectionWrapper( session ); Session wrapped = ( Session ) Proxy.newProxyInstance( Session.class.getClassLoader(), - SESS_PROXY_INTERFACES, + SESSION_PROXY_INTERFACES, wrapper ); // yick! need this for proper serialization/deserialization handling... @@ -222,8 +223,9 @@ public class ThreadLocalSessionContext implements CurrentSessionContext { } /** - * Unassociate a previously bound session from the current thread of execution. + * Disassociates a previously bound session from the current thread of execution. * + * @param factory The factory for which the session should be unbound. * @return The session which was unbound. */ public static Session unbind(SessionFactory factory) { @@ -237,9 +239,10 @@ public class ThreadLocalSessionContext implements CurrentSessionContext { } protected static Map sessionMap() { - return ( Map ) context.get(); + return context.get(); } + @SuppressWarnings({"unchecked"}) private static void doBind(org.hibernate.Session session, SessionFactory factory) { Map sessionMap = sessionMap(); if ( sessionMap == null ) { diff --git a/hibernate-core/src/test/java/org/hibernate/test/connections/HibernateCreateBlobFailedCase.java b/hibernate-core/src/test/java/org/hibernate/test/connections/HibernateCreateBlobFailedCase.java new file mode 100644 index 0000000000..dcbffa6def --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/connections/HibernateCreateBlobFailedCase.java @@ -0,0 +1,68 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.connections; + +import org.hibernate.Hibernate; +import org.hibernate.Session; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; +import org.hibernate.testing.junit.functional.FunctionalTestCase; + +import java.sql.Blob; +import java.sql.Clob; +import java.sql.SQLException; + +/** + * Test originally developed to verify and fix HHH-5550 + * + * @author Steve Ebersole + */ +public class HibernateCreateBlobFailedCase extends FunctionalTestCase { + public HibernateCreateBlobFailedCase(String string) { + super( string ); + } + + @Override + public String[] getMappings() { + return new String[] { "connections/Silly.hbm.xml" }; + } + + @Override + public void configure(Configuration cfg) { + super.configure( cfg ); + cfg.setProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread" ); + } + + public void testLobCreation() throws SQLException { + Session session = sfi().getCurrentSession(); + session.beginTransaction(); + Blob blob = Hibernate.getLobCreator( session ).createBlob( new byte[] {} ); + blob.free(); + Clob clob = Hibernate.getLobCreator( session ).createClob( "Steve" ); + clob.free(); + session.getTransaction().commit(); + assertFalse( session.isOpen() ); + } + +}