⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sessionfactoryutils.java

📁 Java/J2EE application framework based on [Expert One-on-One J2EE Design and Development] by Rod John
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	 * @param allowSynchronization if a new Hibernate Session is supposed to be
	 * registered with transaction synchronization (if synchronization is active)
	 * @param allowCreate if a new Session should be created if no thread-bound found
	 * @return the Hibernate Session
	 * @throws DataAccessResourceFailureException if the Session couldn't be created
	 * @throws IllegalStateException if no thread-bound Session found and allowCreate false
	 */
	private static Session getSession(
			SessionFactory sessionFactory, Interceptor entityInterceptor,
			SQLExceptionTranslator jdbcExceptionTranslator, boolean allowSynchronization, boolean allowCreate)
			throws DataAccessResourceFailureException, IllegalStateException {

		SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
		if (sessionHolder != null) {
			// pre-bound Hibernate Session
			if (TransactionSynchronizationManager.isSynchronizationActive()) {
				// Spring transaction management is active ->
				// register pre-bound Session with it for transactional flushing.
				if (allowSynchronization && !sessionHolder.isSynchronizedWithTransaction()) {
					logger.debug("Registering Spring transaction synchronization for existing Hibernate session");
					TransactionSynchronizationManager.registerSynchronization(
							new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, false));
					sessionHolder.setSynchronizedWithTransaction(true);
					FlushMode flushMode = sessionHolder.getSession().getFlushMode();
					if (FlushMode.NEVER.equals(flushMode)) {
						sessionHolder.getSession().setFlushMode(FlushMode.AUTO);
						sessionHolder.setPreviousFlushMode(flushMode);
					}
				}
				return sessionHolder.getSession();
			}
			else {
				// no Spring transaction management active
				TransactionManager jtaTm = getJtaTransactionManager(sessionFactory, sessionHolder.getAnySession());
				if (jtaTm != null) {
					// Check whether JTA transaction management is active ->
					// fetch pre-bound Session for the current JTA transaction, if any.
					// (just necessary for JTA transaction suspension, with an individual
					// Hibernate Session per currently active/suspended transaction)
					try {
						int jtaStatus = jtaTm.getStatus();
						if (jtaStatus == Status.STATUS_ACTIVE || jtaStatus == Status.STATUS_MARKED_ROLLBACK) {
							// look for transaction-specific Session
							Session session = sessionHolder.getSession(jtaTm.getTransaction());
							if (session != null) {
								return session;
							}
						}
						else {
							// no transaction active -> simply return default thread-bound Session
							return sessionHolder.getSession();
						}
					}
					catch (SystemException ex) {
						throw new DataAccessResourceFailureException("Could not check JTA transaction", ex);
					}
				}
				else {
					// no JTA TransactionManager -> simply return default thread-bound Session
					return sessionHolder.getSession();
				}
			}
		}

		if (!allowCreate) {
			throw new IllegalStateException("No Hibernate session bound to thread, " +
			    "and configuration does not allow creation of new one here");
		}

		logger.debug("Opening Hibernate session");
		try {
			Session session = (entityInterceptor != null ?
			    sessionFactory.openSession(entityInterceptor) : sessionFactory.openSession());

			if (allowSynchronization) {
				// Use same Session for further Hibernate actions within the transaction.
				// Thread object will get removed by synchronization at transaction completion.

				if (TransactionSynchronizationManager.isSynchronizationActive()) {
					// We're within a Spring-managed transaction, possibly from JtaTransactionManager.
					logger.debug("Registering Spring transaction synchronization for new Hibernate session");
					sessionHolder = new SessionHolder(session);
					sessionHolder.setSynchronizedWithTransaction(true);
					TransactionSynchronizationManager.registerSynchronization(
							new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, true));
					TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
				}

				else {
					// JTA synchronization is only possible with a javax.transaction.TransactionManager.
					// We'll check the Hibernate SessionFactory: If a TransactionManagerLookup is specified
					// in Hibernate configuration, it will contain a TransactionManager reference.
					TransactionManager jtaTm = getJtaTransactionManager(sessionFactory, session);
					if (jtaTm != null) {
						try {
							int jtaStatus = jtaTm.getStatus();
							if (jtaStatus == Status.STATUS_ACTIVE || jtaStatus == Status.STATUS_MARKED_ROLLBACK) {
								logger.debug("Registering JTA transaction synchronization for new Hibernate session");
								javax.transaction.Transaction jtaTx = jtaTm.getTransaction();
								boolean newHolder = false;
								// register with existing SessionHolder or create a new one
								if (sessionHolder == null) {
									sessionHolder = new SessionHolder(jtaTx, session);
									sessionHolder.setSynchronizedWithTransaction(true);
									newHolder = true;
								}
								else {
									sessionHolder.addSession(jtaTx, session);
								}
								jtaTx.registerSynchronization(
										new JtaSessionSynchronization(
												new SpringSessionSynchronization(
												    sessionHolder, sessionFactory, jdbcExceptionTranslator, true),
												jtaTm));
								if (newHolder) {
									TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
								}
							}
						}
						catch (Exception ex) {
							throw new DataAccessResourceFailureException(
							    "Could not register synchronization with JTA TransactionManager", ex);
						}
					}
				}
			}
			return session;
		}
		catch (JDBCException ex) {
			// SQLException underneath
			throw new DataAccessResourceFailureException(
			    "Could not open Hibernate session", ex.getSQLException());
		}
		catch (HibernateException ex) {
			throw new DataAccessResourceFailureException("Could not open Hibernate session", ex);
		}
	}


	/**
	 * Apply the current transaction timeout, if any, to the given
	 * Hibernate Query object.
	 * @param query the Hibernate Query object
	 * @param sessionFactory Hibernate SessionFactory that the Query was created for
	 */
	public static void applyTransactionTimeout(Query query, SessionFactory sessionFactory) {
		SessionHolder sessionHolder =
		    (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
		if (sessionHolder != null && sessionHolder.hasTimeout()) {
			query.setTimeout(sessionHolder.getTimeToLiveInSeconds());
		}
	}

	/**
	 * Apply the current transaction timeout, if any, to the given
	 * Hibernate Criteria object.
	 * @param criteria the Hibernate Criteria object
	 * @param sessionFactory Hibernate SessionFactory that the Criteria was created for
	 */
	public static void applyTransactionTimeout(Criteria criteria, SessionFactory sessionFactory) {
		SessionHolder sessionHolder =
		    (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
		if (sessionHolder != null && sessionHolder.hasTimeout()) {
			criteria.setTimeout(sessionHolder.getTimeToLiveInSeconds());
		}
	}

	/**
	 * Convert the given HibernateException to an appropriate exception from the
	 * org.springframework.dao hierarchy. Note that it is advisable to handle
	 * JDBCException specifically by using an SQLExceptionTranslator for the
	 * underlying SQLException.
	 * @param ex HibernateException that occured
	 * @return the corresponding DataAccessException instance
	 * @see HibernateAccessor#convertHibernateAccessException
	 * @see HibernateAccessor#convertJdbcAccessException
	 * @see HibernateTransactionManager#convertHibernateAccessException
	 * @see HibernateTransactionManager#convertJdbcAccessException
	 * @see net.sf.hibernate.JDBCException#getSQLException
	 * @see org.springframework.jdbc.support.SQLExceptionTranslator
	 */
	public static DataAccessException convertHibernateAccessException(HibernateException ex) {
		if (ex instanceof JDBCException) {
			// SQLException during Hibernate access: only passed in here from custom code,
			// as HibernateTemplate etc will use SQLExceptionTranslator-based handling
			return new HibernateJdbcException((JDBCException) ex);
		}
		if (ex instanceof UnresolvableObjectException) {
			return new HibernateObjectRetrievalFailureException((UnresolvableObjectException) ex);
		}
		if (ex instanceof ObjectNotFoundException) {
			return new HibernateObjectRetrievalFailureException((ObjectNotFoundException) ex);
		}
		if (ex instanceof ObjectDeletedException) {
			return new HibernateObjectRetrievalFailureException((ObjectDeletedException) ex);
		}
		if (ex instanceof WrongClassException) {
			return new HibernateObjectRetrievalFailureException((WrongClassException) ex);
		}
		if (ex instanceof StaleObjectStateException) {
			return new HibernateOptimisticLockingFailureException((StaleObjectStateException) ex);
		}
		if (ex instanceof QueryException) {
			return new HibernateQueryException((QueryException) ex);
		}
		if (ex instanceof PersistentObjectException) {
			return new InvalidDataAccessApiUsageException(ex.getMessage());
		}
		if (ex instanceof TransientObjectException) {
			return new InvalidDataAccessApiUsageException(ex.getMessage());
		}
		// fallback
		return new HibernateSystemException(ex);
	}


	/**
	 * Return if deferred close is active for the current thread
	 * and the given SessionFactory.
	 * @param sessionFactory Hibernate SessionFactory
	 */
	public static boolean isDeferredCloseActive(SessionFactory sessionFactory) {
		Map holderMap = (Map) deferredCloseHolder.get();
		return (holderMap != null && holderMap.containsKey(sessionFactory));
	}

	/**
	 * Initialize deferred close for the current thread and the given SessionFactory.
	 * Sessions will not be actually closed on close calls then, but rather at a
	 * processDeferredClose call at a finishing point (like request completion).
	 * <p>Used by OpenSessionInViewFilter and OpenSessionInViewInterceptor
	 * when not configured for a single session.
	 * @param sessionFactory Hibernate SessionFactory
	 * @see #processDeferredClose
	 * @see #closeSessionIfNecessary
	 * @see org.springframework.orm.hibernate.support.OpenSessionInViewFilter#setSingleSession
	 * @see org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor#setSingleSession
	 */
	public static void initDeferredClose(SessionFactory sessionFactory) {
		logger.debug("Initializing deferred close of Hibernate sessions");
		Map holderMap = (Map) deferredCloseHolder.get();
		if (holderMap == null) {
			holderMap = new HashMap();
			deferredCloseHolder.set(holderMap);
		}
		holderMap.put(sessionFactory, new HashSet());
	}

	/**
	 * Process Sessions that have been registered for deferred close
	 * for the given SessionFactory.
	 * @param sessionFactory Hibernate SessionFactory
	 * @see #initDeferredClose
	 * @see #closeSessionIfNecessary
	 */
	public static void processDeferredClose(SessionFactory sessionFactory) {
		Map holderMap = (Map) deferredCloseHolder.get();
		if (holderMap == null || !holderMap.containsKey(sessionFactory)) {
			throw new IllegalStateException("Deferred close not active for SessionFactory [" + sessionFactory + "]");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -