Code example for WebRequest

Methods: getAttribute, setAttribute

0
 * changing the default flush mode (through the 
 * {@link #setFlushMode(int) "flushMode"} property). 
 * 
 * <p>In contrast to {@link OpenSessionInViewFilter}, this interceptor is 
 * configured in a Spring application context and can thus take advantage of bean 
 * wiring. It inherits common Hibernate configuration properties from 
 * {@link org.springframework.orm.hibernate3.HibernateAccessor}, 
 * to be configured in a bean definition. 
 * 
 * <p><b>WARNING:</b> Applying this interceptor to existing logic can cause issues 
 * that have not appeared before, through the use of a single Hibernate 
 * {@code Session} for the processing of an entire request. In particular, the 
 * reassociation of persistent objects with a Hibernate {@code Session} has to 
 * occur at the very beginning of request processing, to avoid clashes with already 
 * loaded instances of the same objects. 
 * 
 * <p>Alternatively, turn this interceptor into deferred close mode, by specifying 
 * "singleSession"="false": It will not use a single session per request then, 
 * but rather let each data access operation or transaction use its own session 
 * (as would be the case without Open Session in View). Each of those sessions will 
 * be registered for deferred close though, which will actually be processed at 
 * request completion. 
 * 
 * <p>A single session per request allows for the most efficient first-level caching, 
 * but can cause side effects, for example on {@code saveOrUpdate} or when 
 * continuing after a rolled-back transaction. The deferred close strategy is as safe 
 * as no Open Session in View in that respect, while still allowing for lazy loading 
 * in views (but not providing a first-level cache for the entire request). 
 * 
 * @author Juergen Hoeller 
 * @since 1.2 
 * @see #setSingleSession 
 * @see #setFlushMode 
 * @see OpenSessionInViewFilter 
 * @see OpenSessionInterceptor 
 * @see org.springframework.orm.hibernate3.HibernateTransactionManager 
 * @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession 
 * @see org.springframework.transaction.support.TransactionSynchronizationManager 
 * @see org.hibernate.SessionFactory#getCurrentSession() 
 */ 
public class OpenSessionInViewInterceptor extends HibernateAccessor implements AsyncWebRequestInterceptor { 
 
	/** 
	 * Suffix that gets appended to the {@code SessionFactory} 
	 * {@code toString()} representation for the "participate in existing 
	 * session handling" request attribute. 
	 * @see #getParticipateAttributeName 
	 */ 
	public static final String PARTICIPATE_SUFFIX = ".PARTICIPATE"; 
 
 
	private boolean singleSession = true; 
 
 
	/** 
	 * Create a new {@code OpenSessionInViewInterceptor}, 
	 * turning the default flushMode to {@code FLUSH_NEVER}. 
	 * @see #setFlushMode 
	 */ 
	public OpenSessionInViewInterceptor() { 
		setFlushMode(FLUSH_NEVER); 
	} 
 
	/** 
	 * Set whether to use a single session for each request. Default is "true". 
	 * <p>If set to false, each data access operation or transaction will use 
	 * its own session (like without Open Session in View). Each of those 
	 * sessions will be registered for deferred close, though, actually 
	 * processed at request completion. 
	 * @see SessionFactoryUtils#initDeferredClose 
	 * @see SessionFactoryUtils#processDeferredClose 
	 */ 
	public void setSingleSession(boolean singleSession) { 
		this.singleSession = singleSession; 
	} 
 
	/** 
	 * Return whether to use a single session for each request. 
	 */ 
	protected boolean isSingleSession() { 
		return singleSession; 
	} 
 
 
	/** 
	 * Open a new Hibernate {@code Session} according to the settings of this 
	 * {@code HibernateAccessor} and bind it to the thread via the 
	 * {@link TransactionSynchronizationManager}. 
	 * @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession 
	 */ 
	@Override 
	public void preHandle(WebRequest request) throws DataAccessException { 
		String participateAttributeName = getParticipateAttributeName(); 
 
		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); 
		if (asyncManager.hasConcurrentResult()) { 
			if (applySessionBindingInterceptor(asyncManager, participateAttributeName)) { 
				return; 
			} 
		} 
 
		if ((isSingleSession() && TransactionSynchronizationManager.hasResource(getSessionFactory())) || 
			SessionFactoryUtils.isDeferredCloseActive(getSessionFactory())) { 
			// Do not modify the Session: just mark the request accordingly. 
			Integer count = (Integer) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST); 
			int newCount = (count != null ? count + 1 : 1); 
			request.setAttribute(getParticipateAttributeName(), newCount, WebRequest.SCOPE_REQUEST); 
		} 
		else { 
			if (isSingleSession()) { 
				// single session mode 
				logger.debug("Opening single Hibernate Session in OpenSessionInViewInterceptor");