001/*
002 * Copyright 2002-2012 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.orm.hibernate3;
018
019import java.util.Map;
020import java.util.concurrent.ConcurrentHashMap;
021
022import org.hibernate.FlushMode;
023import org.hibernate.Session;
024import org.hibernate.Transaction;
025
026import org.springframework.transaction.support.ResourceHolderSupport;
027import org.springframework.util.Assert;
028
029/**
030 * Session holder, wrapping a Hibernate Session and a Hibernate Transaction.
031 * HibernateTransactionManager binds instances of this class to the thread,
032 * for a given SessionFactory.
033 *
034 * <p>Note: This is an SPI class, not intended to be used by applications.
035 *
036 * @author Juergen Hoeller
037 * @since 1.2
038 * @see HibernateTransactionManager
039 * @see SessionFactoryUtils
040 * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x
041 */
042@Deprecated
043public class SessionHolder extends ResourceHolderSupport {
044
045        private static final Object DEFAULT_KEY = new Object();
046
047        /**
048         * This Map needs to be concurrent because there might be multi-threaded
049         * access in the case of JTA with remote transaction propagation.
050         */
051        private final Map<Object, Session> sessionMap = new ConcurrentHashMap<Object, Session>(1);
052
053        private Transaction transaction;
054
055        private FlushMode previousFlushMode;
056
057
058        public SessionHolder(Session session) {
059                addSession(session);
060        }
061
062        public SessionHolder(Object key, Session session) {
063                addSession(key, session);
064        }
065
066
067        public Session getSession() {
068                return getSession(DEFAULT_KEY);
069        }
070
071        public Session getSession(Object key) {
072                return this.sessionMap.get(key);
073        }
074
075        public Session getValidatedSession() {
076                return getValidatedSession(DEFAULT_KEY);
077        }
078
079        public Session getValidatedSession(Object key) {
080                Session session = this.sessionMap.get(key);
081                // Check for dangling Session that's around but already closed.
082                // Effectively an assertion: that should never happen in practice.
083                // We'll seamlessly remove the Session here, to not let it cause
084                // any side effects.
085                if (session != null && !session.isOpen()) {
086                        this.sessionMap.remove(key);
087                        session = null;
088                }
089                return session;
090        }
091
092        public Session getAnySession() {
093                if (!this.sessionMap.isEmpty()) {
094                        return this.sessionMap.values().iterator().next();
095                }
096                return null;
097        }
098
099        public void addSession(Session session) {
100                addSession(DEFAULT_KEY, session);
101        }
102
103        public void addSession(Object key, Session session) {
104                Assert.notNull(key, "Key must not be null");
105                Assert.notNull(session, "Session must not be null");
106                this.sessionMap.put(key, session);
107        }
108
109        public Session removeSession(Object key) {
110                return this.sessionMap.remove(key);
111        }
112
113        public boolean containsSession(Session session) {
114                return this.sessionMap.containsValue(session);
115        }
116
117        public boolean isEmpty() {
118                return this.sessionMap.isEmpty();
119        }
120
121        public boolean doesNotHoldNonDefaultSession() {
122                return this.sessionMap.isEmpty() ||
123                                (this.sessionMap.size() == 1 && this.sessionMap.containsKey(DEFAULT_KEY));
124        }
125
126
127        public void setTransaction(Transaction transaction) {
128                this.transaction = transaction;
129        }
130
131        public Transaction getTransaction() {
132                return this.transaction;
133        }
134
135        public void setPreviousFlushMode(FlushMode previousFlushMode) {
136                this.previousFlushMode = previousFlushMode;
137        }
138
139        public FlushMode getPreviousFlushMode() {
140                return this.previousFlushMode;
141        }
142
143
144        @Override
145        public void clear() {
146                super.clear();
147                this.transaction = null;
148                this.previousFlushMode = null;
149        }
150
151}