1 /* 2 * Copyright 2002-2011 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.springframework.orm.hibernate4; 18 19 import javax.transaction.TransactionManager; 20 21 import org.hibernate.FlushMode; 22 import org.hibernate.HibernateException; 23 import org.hibernate.Session; 24 import org.hibernate.context.spi.CurrentSessionContext; 25 import org.hibernate.engine.spi.SessionFactoryImplementor; 26 import org.hibernate.service.jta.platform.spi.JtaPlatform; 27 28 import org.springframework.transaction.support.TransactionSynchronizationManager; 29 30 /** 31 * Implementation of Hibernate 3.1's CurrentSessionContext interface 32 * that delegates to Spring's SessionFactoryUtils for providing a 33 * Spring-managed current Session. 34 * 35 * <p>This CurrentSessionContext implementation can also be specified in custom 36 * SessionFactory setup through the "hibernate.current_session_context_class" 37 * property, with the fully qualified name of this class as value. 38 * 39 * @author Juergen Hoeller 40 * @since 3.1 41 */ 42 @SuppressWarnings("serial") 43 public class SpringSessionContext implements CurrentSessionContext { 44 45 private final SessionFactoryImplementor sessionFactory; 46 47 private final CurrentSessionContext jtaSessionContext; 48 49 50 /** 51 * Create a new SpringSessionContext for the given Hibernate SessionFactory. 52 * @param sessionFactory the SessionFactory to provide current Sessions for 53 */ SpringSessionContext(SessionFactoryImplementor sessionFactory)54 public SpringSessionContext(SessionFactoryImplementor sessionFactory) { 55 this.sessionFactory = sessionFactory; 56 JtaPlatform jtaPlatform = sessionFactory.getServiceRegistry().getService(JtaPlatform.class); 57 TransactionManager transactionManager = jtaPlatform.retrieveTransactionManager(); 58 this.jtaSessionContext = (transactionManager != null ? new SpringJtaSessionContext(sessionFactory) : null); 59 } 60 61 62 /** 63 * Retrieve the Spring-managed Session for the current thread, if any. 64 */ currentSession()65 public Session currentSession() throws HibernateException { 66 Object value = TransactionSynchronizationManager.getResource(this.sessionFactory); 67 if (value instanceof Session) { 68 return (Session) value; 69 } 70 else if (value instanceof SessionHolder) { 71 SessionHolder sessionHolder = (SessionHolder) value; 72 Session session = sessionHolder.getSession(); 73 if (TransactionSynchronizationManager.isSynchronizationActive() && 74 !sessionHolder.isSynchronizedWithTransaction()) { 75 TransactionSynchronizationManager.registerSynchronization( 76 new SpringSessionSynchronization(sessionHolder, this.sessionFactory)); 77 sessionHolder.setSynchronizedWithTransaction(true); 78 // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session 79 // with FlushMode.MANUAL, which needs to allow flushing within the transaction. 80 FlushMode flushMode = session.getFlushMode(); 81 if (FlushMode.isManualFlushMode(flushMode) && 82 !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { 83 session.setFlushMode(FlushMode.AUTO); 84 sessionHolder.setPreviousFlushMode(flushMode); 85 } 86 } 87 return session; 88 } 89 else if (this.jtaSessionContext != null) { 90 Session session = this.jtaSessionContext.currentSession(); 91 if (TransactionSynchronizationManager.isSynchronizationActive()) { 92 TransactionSynchronizationManager.registerSynchronization(new SpringFlushSynchronization(session)); 93 } 94 return session; 95 } 96 else { 97 throw new HibernateException("No Session found for current thread"); 98 } 99 } 100 101 } 102