Introduction to OpenSessionInViewFilter in spring, opensessioninview
Assume that Hibernate manages its sessions through spring in your application. If OpenSessionInViewFilter or OpenSessionInViewInterceptor is not used in your application. The session will be closed after the end of transaction.
If you adopt spring's declarative transaction mode, it will wrap every method of your proxy object (AOP method ). As follows:
<Bean id = "txProxyTemplate" abstract = "true"
Class = "org. springframework. transaction. interceptor. TransactionProxyFactoryBean">
<Property name = "transactionManager" ref = "transactionManager"/>
<Property name = "transactionAttributes">
<Props>
<Prop key = "save *"> PROPAGATION_REQUIRED </prop>
<Prop key = "remove *"> PROPAGATION_REQUIRED </prop>
<Prop key = "*"> PROPAGATION_REQUIRED, readOnly </prop>
</Props>
</Property>
</Bean>
<Bean id = "manager" parent = "txProxyTemplate">
<Property name = "target">
<Bean class = "org. appfuse. service. impl. BaseManager">
<Property name = "dao" ref = "dao"/>
</Bean>
</Property>
</Bean>
The transaction type PROPAGATION_REQUIRED of the save * method of the target class org. appfuse. service. impl. BaseManager, and PROPAGATION_REQUIRED of the remove * Method
The transaction types of other methods are PROPAGATION_REQUIRED and readOnly.
So it seems to you that the session is closed after you call the bean method named "manager.
If OpenSessionInViewFilter or OpenSessionInViewInterceptor is used in an application, all opened sessions are saved in a thread variable. Passed before the thread exits
OpenSessionInViewFilter or OpenSessionInViewInterceptor disconnect these sessions. Why? This is mainly to implement the delayed Loading Function of Hibernate. Based on one request
A hibernate session principle.
The description of OpenSessionInViewFilter in spring is as follows:
It is a Servlet2.3 filter used to bind a Hibernate Session to the thread corresponding to a complete request process. The purpose is to implement the "Open Session in View" mode.
For example, it allows delayed loading of the desired objects after the transaction is committed.
This filter is similar to HibernateInterceptor: It is implemented through a thread. Whether it is an application without transactions or an application with business-layer transactions (through HibernateTransactionManager or
JtaTransactionManager. In the latter case, the transaction will automatically use the Session bound by the filter to perform related operations and complete the commit operations according to the actual situation.
Warning if a single HIbernate Session is used during a request in your application, using this filter will generate some problems that were not encountered before. Note that
The Hibernate Session reorganizes the relationships between persistent objects at the beginning of the request. To avoid conflicts with the same object that has been loaded.
Alternatively, we can adjust this filter to the deferred closing mode by specifying "singleSession" = "false. In this way, a single Session is not used during a request. Each data access or transaction-related
All operations use their own sessions (a bit like not using Open sessions in View ). these sessions are registered in the delayed close mode, even if the related operations have been completed in this request.
"One request for one session" is very effective for the first-level cache, but this can cause side effects. For example, during saveOrUpdate or after transaction rollback, although it is as safe as "no Open Session in View.
However, it allows delayed loading.
It searches for the Session factory in the context root of spring web applications. It also supports bean
Name to find the session factory. The default bean name is "sessionFactory", which is used to find the SessionFactory every request to avoid problems caused by the initialization sequence (when ContextLoaderServlet is used
When integrating spring, the spring application context is initialized only after the filter ).
By default, the filter does not synchronize the Hibernate Session. This is because it considers that this work is done through transactions at the business layer. And the FlushMode of HibernateAccessors is FLUSH_EAGER. If you
You want the filter to synchronize sessions after the request is complete. you need to overwrite its closeSession method. In this method, you need to synchronize the session before calling the closing session operation of the parent class. in addition, you need to overwrite its getSession ()
Method. Returns a session whose FlushMode is not the default FlushMode. NEVER. Note that the getSession () and closeSession () methods are called only in single session mode.
In the wiki of myfaces, a subclass of OpenSessionInViewFilter is provided as follows:
Public class OpenSessionInViewFilter extends org. springframework. orm. hibernate3.support. OpenSessionInViewFilter {
/**
* We do a different flushmode than in the codebase
* Here
*/
Protected Session getSession (SessionFactory sessionFactory) throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils. getSession (sessionFactory, true );
Session. setFlushMode (FlushMode. COMMIT );
Return session;
}
/**
* We do an explicit flush here just in case
* We do not have an automatic flush
*/
Protected void closeSession (Session session, SessionFactory factory ){
Session. flush ();
Super. closeSession (session, factory );
}
}
What is the role of opensessioninview in java framework spring?
When the load method is used in hibernate, the session is closed when the data is not actually obtained. When we really want to obtain the data, the load will be forced to load the data, and the session has been closed at this time, therefore, an exception occurs. Typically, in MVC mode, when the persistent layer is called on the M layer to obtain data (the persistent layer uses the load method to load data), when the call ends, the session is closed, and we want to use the data in layer V to force the load to load the data. We want the session to be open at this time, this is the so-called Open Session In view. We can use filters to achieve this goal, or use interceptor.
Filter:
?
<! -- Implement the OpenSessionInView listener of Spring before the listener of struts2 -->
<Filter>
<Filter-name> openSessionInViewFilter </filter-name>
<Filter-class>
Org. springframework. orm. hibernate3.support. OpenSessionInViewFilter
</Filter-class>
</Filter>
<Filter-mapping>
<Filter-name> openSessionInViewFilter </filter-name>
<Url-pattern>/* </url-pattern>
</Filter-mapping>
Interceptor:
?
Importorg. springframework. orm. hibernate3.support. HibernateDaoSupport;
PublicclassXxxDAOextendsHibernateDaoSupport {
Publicvoidsave (Xxx transientInstance ){
Try {
GetHibernateTemplate (). save (transientInstance );
} Catch (RuntimeException re ){
Throwre;
}
}
}
The main function of OpenSessionInViewFilter is to bind a Hibernate Session to the thread corresponding to a complete request process. Open Session In View keeps the hibernate session open during the request binding session to the current thread, so that the session can be used throughout the request, for example, in the View layer, PO can also lazy loading data, for example, $ {company. employees }. When the View layer logic is complete, the session will be automatically closed through the doFilter method of Filter or the postHandle method of Interceptor.
In addition, it is best not to write/* in <url-pattern>/* </url-pattern>, because in this case, a session is opened for all URLs, causes performance degradation ;... remaining full text>
Hibernate ing relationship no session or session was closed
Introduction to OpenSessionInViewFilter of spring
Assume that Hibernate manages its sessions through spring in your application. If OpenSessionInViewFilter or OpenSessionInViewInterceptor is not used in your application. The session will be closed after the end of transaction.
If you adopt spring's declarative transaction mode, it will wrap every method of your proxy object (AOP method ). As follows:
<Bean id = "txProxyTemplate" abstract = "true"
Class = "org. springframework. transaction. interceptor. TransactionProxyFactoryBean">
<Property name = "transactionManager" ref = "transactionManager"/>
<Property name = "transactionAttributes">
<Props>
<Prop key = "save *"> PROPAGATION_REQUIRED </prop>
<Prop key = "remove *"> PROPAGATION_REQUIRED </prop>
<Prop key = "*"> PROPAGATION_REQUIRED, readOnly </prop>
</Props>
</Property>
</Bean>
<Bean id = "manager" parent = "txProxyTemplate">
<Property name = "target">
<Bean class = "org. appfuse. service. impl. BaseManager">
<Property name = "dao" ref = "dao"/>
</Bean>
</Property>
</Bean>
The transaction type PROPAGATION_REQUIRED of the save * method of the target class org. appfuse. service. impl. BaseManager, and PROPAGATION_REQUIRED of the remove * Method
The transaction types of other methods are PROPAGATION_REQUIRED and readOnly.
So I feel like sessi... after calling the bean method named "manager">