Hibernate’s Contextual Session

อีกหนึ่งบทความในชุด Hibernate เพื่อเพิ่มความเข้าใจในการใช้งาน ตอนนี้จะนำเสนอ Context
Context คือ ที่เก็บ Session ปัจจุบันที่กำลังทำงานอยู่ คนที่เขียนโปรแกรมโดยใช้ Hibernate ORM จำเป็นต้องหาที่เก็บ Session ซึ่งวิธีเก็บ Session ก็มีได้หลายแบบ ในยุคก่อนเวอร์ชั่น 3.0 ลงไปเมื่อมีการเปิด Session จะนิยมใช้ ThreadLocal และเรียกใช้ผ่าน Helper หน้าตาประมาณนี้

public class HibernateUtil {
	private static Log log = LogFactory.getLog(HibernateUtil.class);
	
	private static SessionFactory factory;
	private static ThreadLocal hibernateHolder = new ThreadLocal();
	
	
	public void init() throws ConfigException {
		// Init hibernate building sessionFactory
	}

	public Session getSession() throws HibernateException {
		Session sess = (Session) hibernateHolder.get();

		if ((sess == null) && (factory != null)) {
			sess = factory.openSession();
			hibernateHolder.set(sess);
		}

		return sess;
	}

	public void closeSession() throws HibernateException {
		Session sess = (Session) hibernateHolder.get();

		if (sess != null) {
			hibernateHolder.set(null);

			try {
				sess.close();
			} catch (HibernateException ex) {
				log.error(ex);
			}
		}
	}

	//Bla bla bla method
	
}

จะเห็นว่าเราต้องเป็นคนรับผิดชอบชีวิตของ Session ด้วยตัวเอง พอมาเวอร์ชั่น 3.0.1 ทางทีมงานพัฒนาได้เพิ่มเมธอด SessionFactory.getCurrentSession() ซึ่งการทำงานข้างในจะเป็นการใช้ JTA transaction เป็นคนจัดการ scope (transaction) และ context ของ Session ปัจจุบันที่กำลังใช้งาน (เรียกว่าเป็นการส่งคืนให้ Hibernate เป็นคนจัดการ Session)

จนมาถึงเวอร์ชั่น 3.1 ก็ได้มีการปรับเปลี่ยนการทำงานของเมธอด SessionFactory.getCurrentSession() ให้สามารถปรับเปลี่ยนได้ตามความต้องการ (pluggable) โดยกำหนดค่าผ่าน config ที่ชื่อ hibernate.current_session_context_class ซึ่งคลาสที่จะทำการ plug เข้ามาจะต้องทำการ implement interface ที่ชื่อ org.hibernate.context.spi.CurrentSessionContext โดย Hibernate แถมมาให้ 3 คลาสคือ

  • org.hibernate.context.internal.JTASessionContext
  • org.hibernate.context.internal.ThreadLocalSessionContext
  • org.hibernate.context.internal.ManagedSessionContext

โดยสองคลาสแรกจะใช้รูปแบบ session-per-request (“one session – one database transaction”) และกำหนดค่าใน config ด้วยชื่อสั้นๆ คือ “jta“, “thread” และ “managed” ตามลำดับ
ในการเลือกใช้งานมีวิธีเลือกดังนี้

  • thread” สำหรับ standalone application
  • jta” สำหรับรันบนสภาพแวดล้อมแบบ Java EE
  • managed” เมื่อไม่ต้องการใช้ Hibernate ควบคุม Transaction เช่นต้องการใช้ transaction manager ของ application server หรือในการทำ unit test เราไม่สามารถ reuse Session ได้ ต้องทำการ manual เอง http://www.17od.com/2006/11/06/using-managed-sessions-in-hibernate-to-ease-unit-testing/

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s