- 浏览: 223988 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (226)
- websphere (12)
- Websphere Portlet Factory (2)
- portal (8)
- SOA (14)
- Requirement (5)
- Management (23)
- Open Source (9)
- design (21)
- JDK (34)
- Diary (16)
- Database (26)
- UI (18)
- Audio (1)
- Security (5)
- 水平网站 (2)
- 其他 (6)
- J2EE事务相关 (8)
- Spring (3)
- Integration (3)
- Mobile Programming (1)
- Cloud (2)
- 性能调优 (11)
- Hibernate (5)
- 算法 (1)
最新评论
-
hanmiao:
我在IBM网站上找到这篇文章,比较详细的介绍了信息分片与信息分 ...
Websphere MQ -
lancezhcj:
...
Oracle索引 -
shaier:
讲的很不错啊!
SERVICE_NAME, SID和schema区别 -
echohfut:
好久没有关注了。但是取下来的代码怎么导入Eclipse呢?
liferay笔记 -
webee:
已经有ide了!命令都可以不要了!
liferay笔记
摘自:http://community.jboss.org/wiki/OpenSessioninView
1. 问题描述
A common issue in a typical (web-)application is the rendering of the view, after the main logic of the action has been completed, and therefore, the Hibernate Session has already been closed and the database transaction has ended. If you access detached objects that have been loaded in the Session inside your JSP (or any other view rendering mechanism), you might hit an unloaded collection or a proxy that isn't initialized. The exception you get is: LazyInitializationException: Session has been closed (or a very similar message).
比如页面是学生信息显示,学生实体对象包含一个课程实体列表,并且采用惰性装载。那么页面显示学生的课程信息时可能Session已关闭,事务已提交,hibernate会抛出上面的异常。
基本上问题出现在一次request 与 response 之间layz loading的对象上。open session in view解决方案也是应用在相应的scope内。如果是用JPA,那么对应Session的是EntityManager,相应的是open entity manager in view.
如果渲染发生在servlet中,在servlet中打开和关闭Session(Session per Request"), 这样是没问题的。但如果渲染是用JSP,那么就有这里所说的问题,这时就需要Open Session in View的filter方式。Filter后处理发生在 “渲染JSP模板生成Html” 后, 这时候才关闭Session或者EntityManager
2. 解决方案
2.1
为detached objects 重新开一个session
2.2 open session in view
in most applications you need the following: when an HTTP request has to be handled, a new Session and database transaction will begin. Right before the response is send to the client, and after all the work has been done, the transaction will be committed, and the Session will be closed. A good standard interceptor in a servlet container is a ServletFilter .
public class HibernateSessionRequestFilter implements Filter { private static Log log = LogFactory.getLog(HibernateSessionRequestFilter.class); private SessionFactory sf; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { log.debug("Starting a database transaction"); sf.getCurrentSession().beginTransaction(); // Call the next filter (continue request processing) chain.doFilter(request, response); // Commit and cleanup log.debug("Committing the database transaction"); sf.getCurrentSession().getTransaction().commit(); } catch (StaleObjectStateException staleEx) { log.error("This interceptor does not implement optimistic concurrency control!"); log.error("Your application will not work until you add compensation actions!"); // Rollback, close everything, possibly compensate for any permanent changes // during the conversation, and finally restart business conversation. Maybe // give the user of the application a chance to merge some of his work with // fresh data... what you do here depends on your applications design. throw staleEx; } catch (Throwable ex) { // Rollback only ex.printStackTrace(); try { if (sf.getCurrentSession().getTransaction().isActive()) { log.debug("Trying to rollback database transaction after exception"); sf.getCurrentSession().getTransaction().rollback(); } } catch (Throwable rbEx) { log.error("Could not rollback transaction after exception!", rbEx); } // Let others handle it... maybe another interceptor for exceptions? throw new ServletException(ex); } } public void init(FilterConfig filterConfig) throws ServletException { log.debug("Initializing filter..."); log.debug("Obtaining SessionFactory from static HibernateUtil singleton"); sf = HibernateUtil.getSessionFactory(); } public void destroy() {} }
<filter> <filter-name>HibernateFilter</filter-name> <filter-class>my.package.HibernateSessionRequestFilter</filter-class> </filter> <filter-mapping> <filter-name>HibernateFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
public class ItemDAO { Session currentSession; public ItemDAO() { currentSession = HibernateUtil.getSessionFactory().getCurrentSession(); } public Item getItemById(Long itemId) { return (Item) currentSession.load(Item.class, itemId); } }
public String execute(HttpRequest request) { Long itemId = request.getParameter(ITEM_ID); ItemDAO dao = new ItemDAO(); request.setAttribute( RESULT, dao.getItemById(itemId) ); return "success"; }
3. filter for long conversation 长事务
If you'd like to use a single Session for several database transactions, you either have to implement it completely yourself, or you have to use the built-in "application managed" strategy:
To enable the application-managed "current" Session strategy, set your hibernate.current_session_context_class configuration property to org.hibernate.context.ManagedSessionContext (or simply "managed" in Hibernate 3.2). You can now bind and unbind the "current" Session with static methods, and control the FlushMode and flushing manually.
public class HibernateSessionConversationFilter implements Filter { private static Log log = LogFactory.getLog(HibernateSessionConversationFilter.class); private SessionFactory sf; public static final String HIBERNATE_SESSION_KEY = "hibernateSession"; public static final String END_OF_CONVERSATION_FLAG = "endOfConversation"; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { org.hibernate.classic.Session currentSession; // Try to get a Hibernate Session from the HttpSession HttpSession httpSession = ((HttpServletRequest) request).getSession(); Session disconnectedSession = (Session) httpSession.getAttribute(HIBERNATE_SESSION_KEY); try { // Start a new conversation or in the middle? if (disconnectedSession == null) { log.debug(">>> New conversation"); currentSession = sf.openSession(); currentSession.setFlushMode(FlushMode.NEVER); } else { log.debug("< Continuing conversation"); currentSession = (org.hibernate.classic.Session) disconnectedSession; } log.debug("Binding the current Session"); ManagedSessionContext.bind(currentSession); log.debug("Starting a database transaction"); currentSession.beginTransaction(); log.debug("Processing the event"); chain.doFilter(request, response); log.debug("Unbinding Session after processing"); currentSession = ManagedSessionContext.unbind(sf); // End or continue the long-running conversation? if (request.getAttribute(END_OF_CONVERSATION_FLAG) != null || request.getParameter(END_OF_CONVERSATION_FLAG) != null) { log.debug("Flushing Session"); currentSession.flush(); log.debug("Committing the database transaction"); currentSession.getTransaction().commit(); log.debug("Closing the Session"); currentSession.close(); log.debug("Cleaning Session from HttpSession"); httpSession.setAttribute(HIBERNATE_SESSION_KEY, null); log.debug("<<< End of conversation"); } else { log.debug("Committing database transaction"); currentSession.getTransaction().commit(); log.debug("Storing Session in the HttpSession"); httpSession.setAttribute(HIBERNATE_SESSION_KEY, currentSession); log.debug("> Returning to user in conversation"); } } catch (StaleObjectStateException staleEx) { log.error("This interceptor does not implement optimistic concurrency control!"); log.error("Your application will not work until you add compensation actions!"); // Rollback, close everything, possibly compensate for any permanent changes // during the conversation, and finally restart business conversation. Maybe // give the user of the application a chance to merge some of his work with // fresh data... what you do here depends on your applications design. throw staleEx; } catch (Throwable ex) { // Rollback only try { if (sf.getCurrentSession().getTransaction().isActive()) { log.debug("Trying to rollback database transaction after exception"); sf.getCurrentSession().getTransaction().rollback(); } } catch (Throwable rbEx) { log.error("Could not rollback transaction after exception!", rbEx); } finally { log.error("Cleanup after exception!"); // Cleanup log.debug("Unbinding Session after exception"); currentSession = ManagedSessionContext.unbind(sf); log.debug("Closing Session after exception"); currentSession.close(); log.debug("Removing Session from HttpSession"); httpSession.setAttribute(HIBERNATE_SESSION_KEY, null); } // Let others handle it... maybe another interceptor for exceptions? throw new ServletException(ex); } } public void init(FilterConfig filterConfig) throws ServletException { log.debug("Initializing filter..."); log.debug("Obtaining SessionFactory from static HibernateUtil singleton"); sf = HibernateUtil.getSessionFactory(); } public void destroy() {} }
发表评论
-
hibernate session 管理
2012-02-05 18:44 10541. Session per Operation (Anti ... -
linux命令
2011-07-10 10:37 8161. dirname 与 pwd pwd返回的是执行时当前路 ... -
Hibernate 小知识
2010-06-04 20:41 7731. inverse在one-to-many和many-to- ... -
java quartz
2008-08-29 00:14 683SessionScheduler 中 jobToBeExecu ... -
java quartz
2008-08-29 00:17 641应用observer 模式的一个好处是,处理定时触发的业务逻辑 ... -
java quartz
2008-08-29 00:19 638SessionJob 一定要声明在SessionSchedul ... -
Hibernate笔记
2009-12-16 08:08 6981. inverse=true | false 2. ... -
Hibernate Cache
2009-02-21 20:33 9431. get/load区别 如果记录 ...
相关推荐
Open Session in View模式.PPT
struts2+hibernate3 做的小项目 使用了struts2插件实现pen session in view
在没有使用Spring提供的Open Session In View情况下,因需要在service(or Dao)层里把session关闭,所以lazy loading 为true的话,要在应用层内把关系集合都初始化,如 company.getEmployees(),否则Hibernate抛...
使用Spring提供的Open Session In View而引起Write operations are not allowed in read-only mode (FlushMode.NEVER) 错误解决
SSH整合概述 应用IoC进行整合 应用AOP进行整合 Open Session In View模式
为了练手培训,给大家准备的 Open Session In View 的简单例子,纯代码,大家可以参考,其中主要说了六部分内容: 1.通过接口编程 2.通过spring注入dao到 action 3.通过 open session in view filter 支持 延迟加载...
它演示了MvC 、 SoC 、 IoC 、 DAO 、 Service layer和Open Session in View模式以及其他 J2EE 最佳实践。 该模板可以轻松扩展为功能齐全的基于 Wicket 的 Web 应用程序。 用法 该模板使用 maven 并在 Tomcat7 上...
View detailed session, code lab, and speaker information, including speaker bios, photos, and Google+ profiles +1 sessions right from the app Participate in public #io12 conversations on Google+ Guide...
Open Session; Close Session; Secure Session; Manage Cookie; Block User by Cookie; Create Google Chart; Curl Get Contents; Fetch Wiki Page; Fetch Flickr Stream; Get Yahoo! Answers; Search Yahoo!; Get ...
You can open multiple files in the Open dialogue box, by holding down the Shift or Ctrl key down as you select each file. You can press ESC to return from Full Screen mode to normal mode.
In this tutorial, we'll cover some of the basics of Unicode-encoded text and Unicode files, and how to view and manipulate it in UltraEdit. Search and delete lines found UEStudio and UltraEdit provide...
* Describe Window now also shows the view comments in the header * Export Tables would change nls_date_format in single session mode and dual session mode * Auto Replace now supports Undo to continue...
- fixed bug with URLs in Open Document Text and Open Document Spreadsheet exports - fixed format string in XLS OLE export - fixed format string in XLS BIFF8 export - fixed output of the check boxes ...
Encodes the specified URL by including the session ID in it, or, if encoding is not needed, returns the URL unchanged. -------------------------------------------------------------------------------...
* Multi-select files in project-view (when "double-click to open" is configured in Environment Settings) * Resource files are treated as ordinary files now * Updates in "Project Options/Files" code * ...
更新的内容包含: Version 10.8 (2018-07-07) Bugfix: fixed the error message which occured when running the graphical package manager...引用地址:http://www.open-open.com/lib/view/open1437704662490.html
It is stored in CBCGPGridCtrl::m_PrintParams::m_pageInfo member and in CPrintInfo::m_lpUserData member of the CPrintInfo object used while printing at the current print session. Added an option to ...
File encoding of open files is now stored in the session Build Systems may define a cancel command using the "cancel" key Syntax: Added clear_scopes directive, to give more control over the generated ...
Triggers can now be created in the context of a table or view Folders added for Primary, Unique and Foreign key constraints for views Search Bar enhancements A new Search in files option allows you ...
Added a statusbar to the hexview in memoryview Pointerscan for value scans now add the results to the overflow queue Opening a file and changing bytes do not change them to the file anymore (you need ...