📄 hibernatesessioncontextlistener.java
字号:
/* HibernateSessionContextListener.java
{{IS_NOTE
Purpose:
Description:
History:
Tue Sep 11 12:55:11 2006, Created by henrichen
}}IS_NOTE
Copyright (C) 2006 Potix Corporation. All Rights Reserved.
{{IS_RIGHT
This program is distributed under GPL Version 2.0 in the hope that
it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
*/
package org.zkoss.zkplus.hibernate;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.UiException;
import org.zkoss.zk.ui.Execution;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.util.ExecutionInit;
import org.zkoss.zk.ui.util.ExecutionCleanup;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventThreadInit;
import org.zkoss.zk.ui.event.EventThreadResume;
import org.zkoss.lang.Classes;
import org.zkoss.lang.ThreadLocals;
import org.zkoss.util.logging.Log;
import java.util.Map;
import java.util.HashMap;
import java.lang.reflect.Field;
/**
* <p>Listener to make sure each ZK thread got the same hibernat session context;
* used with Hibernate's "thread" session context (org.hibernate.context.ThreadLocalSessionContext).
* </p>
* <p>
* This listener is used with Hibernate's (version 3.1+) "thread" session context.
* That is, when you specify </p>
* <pre><code>
* hibernate.current_session_context_class = thread
* </code></pre>
*
* <p>then you have to add following lines in application's WEB-INF/zk.xml:</p>
* <pre><code>
* <listener>
* <description>Hibernate thread session context management</description>
* <listener-class>org.zkoss.zkplus.hibernate.HibernateSessionContextListener</listener-class>
* </listener>
* </code></pre>
*
* @author henrichen
*/
public class HibernateSessionContextListener implements ExecutionInit, ExecutionCleanup, EventThreadInit, EventThreadResume {
private static final Log log = Log.lookup(HibernateSessionContextListener.class);
private static final String HIBERNATE_SESSION_MAP = "org.zkoss.zkplus.hibernate.SessionMap";
private static final Object SOMETHING = new Object();
//-- ExecutionInit --//
public void init(Execution exec, Execution parent) {
if (parent == null) { //root execution
//always prepare a ThreadLocal SessionMap in Execution attribute
Map map = getSessionMap();
if (map == null) {
map = new HashMap();
setSessionMap(map); //copy to servlet thread's ThreadLocal
}
exec.setAttribute(HIBERNATE_SESSION_MAP, map); // store in Execution attribute
//20060912, henrichen: tricky. Stuff something into session map to
//prevent the map from being removed from context ThreadLocal by the
//ThreadLocalSessionContext#unbind() when it is empty.
map.put(SOMETHING, null);
}
}
//-- ExecutionCleanup --//
public void cleanup(Execution exec, Execution parent, Throwable ex) {
if (parent == null) { //root execution
Map map = getSessionMap();
if (map != null) {
//20060912, henrichen: tricky. Remove the previously stuffed
//something (when ExecutuionInit#init() is called) from
//session map to make the map possible to be removed by the
//ThreadLocalSessionContext#unbind() when it is empty.
map.remove(SOMETHING);
}
exec.removeAttribute(HIBERNATE_SESSION_MAP);
}
}
//-- EventThreadInit --//
public void prepare(Component comp, Event evt) {
//do nothing
}
public void init(Component comp, Event evt) {
//Copy SessionMap stored in Execution attribute into event's ThreadLocal
Map map = (Map) Executions.getCurrent().getAttribute(HIBERNATE_SESSION_MAP);
setSessionMap(map); //copy to event thread's ThreadLocal
}
//-- EventThreadResume --//
public void beforeResume(Component comp, Event evt) {
//do nothing
}
public void afterResume(Component comp, Event evt) {
//always keep the prepared SessionMap in event's ThreadLocal
Map map = (Map) Executions.getCurrent().getAttribute(HIBERNATE_SESSION_MAP);
setSessionMap(map); //copy to event thread's ThreadLocal
}
public void abortResume(Component comp, Event evt){
//do nothing
}
//-- utilities --//
private void setSessionMap(Map map) {
getContextThreadLocal().set(map);
}
private Map getSessionMap() {
return (Map) getContextThreadLocal().get();
}
private ThreadLocal getContextThreadLocal() {
return ThreadLocals.getThreadLocal("org.hibernate.context.ThreadLocalSessionContext", "context");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -