OpenSession InViewモード


OpenSession InViewモードで解決された問題:
  * ヒベルナの事物境界問題
  * sessionクローズによるhibernaneの遅延による例外負荷の問題
事物の境界:
    一つの物事の完成は業務層で行われるべきですが、物事の作成はデータ層で行われます。これは必ず業務層とデータ層の結合性が強くなります。
遅延ロード例外:
     ご存知のように、遅延負荷は動的代理機構を使用しています。この対象を本当に使う時だけデータベースにアクセスします。しかし、データ層で物事の提出を行ったら、sessionがオフになり、またデータにアクセスすると例外例外例外例外例外例外異常が遅延します。だから、sessionのライフサイクルを大きくして、データにアクセスしてからsessionをオフしなければなりません。
ですから、OpenSession InViewモードで上記の問題を解決できます。
OpenSession InViewモードは非常に重要なクラスを使用する必要があります。
OpenSession InViewモード:
  * フィルタを構築して、ものの作成と提出をフィルタに入れて行う必要があります。
  * セッションの有効範囲を大きくして、セッションを現在のスレッドに置いて、セッションを現在のスレッド内で有効にし、現在のスレッド内でアクセスするのは同じセッションです。
OpenSession InViewモードの欠点:
  *合併性が弱まる
  *メモリの消耗が大きい
1.実体類:

package com.yx.zzg.pojo;

import java.util.Date;

public class User {
	
	private String id;

	private String username;

	private String password;

	private Date createTime;

	private Date endTime;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public Date getEndTime() {
		return endTime;
	}

	public void setEndTime(Date endTime) {
		this.endTime = endTime;
	}
}
2.マッピングファイル:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.yx.zzg.pojo">
	<class name="User" table="t_user">
		<id name="id">
			<!--          -->
			<generator class="uuid" />
		</id>
		<property name="username" unique-key="true" />
		<property name="password" />
		<property name="createTime" />
		<property name="endTime" />
	</class>

</hibernate-mapping>
3.フィルタを提供します。

package com.yx.zzg.servelt;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.yx.zzg.util.HibernateUtil;

public class OpenSessionInView implements Filter {

	public void destroy() {

	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain filter) throws IOException, ServletException {
		Transaction tx = null;
		Session session = null;
		try {
			session = HibernateUtil.getThreadLocalSession();
			tx = session.beginTransaction();
			filter.doFilter(request, response);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
				throw new RuntimeException(e.getMessage(),e);
			}
		} finally {
			HibernateUtil.colseSession();
		}
	}

	public void init(FilterConfig arg0) throws ServletException {

	}

}
4.web.xmlにフィルターを配置する

<filter>
		<filter-name>OpenSessionInView</filter-name>
		<filter-class>com.yx.zzg.servelt.OpenSessionInView</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>OpenSessionInView</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
5 Hibernature Util類:

package com.yx.zzg.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
	
	private static SessionFactory sessionFactory;

	//    ThreadLocal  
	private static ThreadLocal threadSession = new ThreadLocal();

	private HibernateUtil() {

	}

	static {
		Configuration cfg = new Configuration().configure();
		sessionFactory = cfg.buildSessionFactory();
	}

	/**
	 *         session,    ,   session,   session       
	 * @return
	 */
	public static Session getThreadLocalSession() {
		Session session = (Session) threadSession.get();
		if (session == null) {
			session = getSession();
			threadSession.set(session);
		}
		return session;
	}

	/**
	 *   session,        session   null
	 */
	public static void colseSession() {
		Session session = (Session) threadSession.get();
		if (session != null) {
			session.close();
			threadSession.set(null);
		}
	}

	public static Session getSession() {
		return sessionFactory.openSession();
	}

}
6.データ層の方法:

	public User findUserById(String id) {
		User user = (User) HibernateUtil.getThreadLocalSession().load(
				User.class, id);
		return user;
	}