Integrate hibernate into spring-Use your own Transaction Processing

Source: Internet
Author: User

1. Use spring for Transaction Processing

Spring comes with transaction processing. You can use AOP to process transactions in the class and method based on XML and annotation (see the preceding Section). Write down spring's use of annotation for transaction processing:

<!-- transaction --><tx:annotation-driven transaction-manager="txManager"/><bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean><aop:config><aop:pointcut id="serviceOperation1" expression="execution(* syx.zswz.service.impl.*.*(..))" /><aop:pointcut id="serviceOperation2" expression="execution(* syx.zswz.base.DaoBaseImpl.*(..))" /><aop:pointcut id="serviceOperation3" expression="within(syx.zswz.service..*)" /><aop:advisor pointcut-ref="serviceOperation1" advice-ref="txAdvice" /><aop:advisor pointcut-ref="serviceOperation2" advice-ref="txAdvice" /><aop:advisor pointcut-ref="serviceOperation3" advice-ref="txAdvice" /></aop:config><tx:advice id="txAdvice"  transaction-manager="txManager"><tx:attributes><tx:method name="*"  /></tx:attributes></tx:advice>

 

2. Use hibernate for Transaction Processing

I have not understood Spring transaction processing very well, so I am not so handy in using it. In addition, I chose a familiar hbernate transaction processing method (see the previous section ), because spring is used in this project, I want to submit the hibernateutils static class to spring for processing, and add the filter to filter all requests that require transactions. However, because the original filter uses hibernateutil as a static class, you can directly call the static method. However, after being handed over to spring for processing, the filter cannot be normally injected with hibernateutil. When Tomcat is started, an exception is reported. Finally, use the filter entrusted by spring to send the filter to spring for processing. If the struts web project is not used, you can submit the filter, Servlet, and so on to spring for processing:

Web. xml

<filter><filter-name>hibernateSessionFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class><init-param><param-name>targetBeanName</param-name><param-value>hibernateSessionFilter</param-value></init-param></filter><filter-mapping><filter-name>hibernateSessionFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

Beans. xml

<!-- transaction --><bean id="hibernateUtils" class="syx.zswz.util.HibernateUtils"></bean><bean id="hibernateSessionFilter" class="syx.zswz.filter.HibernateSessionFilter"></bean>

Hibernatesessionfilter. Java

public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException,ServletException {HttpServletRequest req = (HttpServletRequest) request;HttpServletResponse resp = (HttpServletResponse) response;String url = req.getRequestURI();// /OA-Study/UserAction!loginUIPattern urlPattern = Pattern.compile("\\w+!\\w+");Matcher m = urlPattern.matcher(url);if(m.matches()) {Session session = hibernateUtils.openSession();Transaction tx = null;try {tx = session.beginTransaction();chain.doFilter(request, response);tx.commit();} catch (Exception e) {if (tx != null) {tx.rollback();}throw new RuntimeException(e);} finally {hibernateUtils.closeAndRemoveSession();}}}

 

Hibernateutils. Java

public class HibernateUtils {private  Map<Thread, Session> sessionMap;@Resource(name="sessionFactory")SessionFactory sessionFactory;public HibernateUtils() {sessionMap = new HashMap<Thread, Session>();}static {}/** * can only use in web filter, beause it should *  remove and clear resources * @return */public  Session openSession() {System.out.println(Thread.currentThread().getStackTrace()[1] + " run in " + new Date());Session session = sessionMap.get(Thread.currentThread());if (session == null) {session = sessionFactory.openSession();sessionMap.put(Thread.currentThread(), session);}return session;}public  Session getCurrentSession() {return sessionMap.get(Thread.currentThread());}public  void closeAndRemoveSession() {System.out.println(Thread.currentThread().getStackTrace()[1]+ " run in " + new Date());//Session session = sessionMap.remove(Thread.currentThread());if (session != null) {session.close();}}}

 

3 hibernate + Struts + spring handle transactions by yourself

If struts is used, you cannot intercept all action requests. You must use the interceptor of struts2 to process the transactions of each action in Interceptor:

Struts. XML (Global interceptor ):

 

 <package name="admin" namespace="/admin" extends="struts-default"><interceptors><interceptor name="hibernateSession" class="syx.zswz.filter.HibernateSessionInterceptor"></interceptor><interceptor-stack name="hibernateSessionStack"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="hibernateSession"></interceptor-ref></interceptor-stack></interceptors><default-interceptor-ref name="hibernateSessionStack"></default-interceptor-ref></package>

Hibernatesessioninterceptor. Java

@Overridepublic String intercept(ActionInvocation actionIvocation) throws Exception {String retStr = null;Session session = hibernateUtils.openSession();Transaction tx = null;try {tx = session.beginTransaction();retStr = actionIvocation.invoke();tx.commit();} catch (Exception e) {if (tx != null) {tx.rollback();}throw new RuntimeException(e);} finally {hibernateUtils.closeAndRemoveSession();}return retStr;}

 

In this way, each struts action request will open a session, and the request will be automatically submitted at the end of the request, similar to the request-level session, and there should be no lazy loading problems, because the session does not have a commit, this can be considered by a system that is not very strong in transaction processing. Of course, it is very fine for that transaction processing control and may need to be processed by spring transactions.

 

Note: I suddenly think of the reason why transaction is not well controlled when I use spirng for transaction processing. It may be because I add all transactions to the service and serviceimpl layers and the underlying daobase, however, my action calls methods in the service layer, and may call several methods a, B, and C, like this:

Xxaction extends actionsupport {

Public String add (){

Servicea. Get ();

Servicea. Update ();

Serviceb. Save (XX );

}

}

When my first servicea. after get () is called, transaction is submitted and session is over. I am servicea. if Update () is returned using the first method, unexpected results may be generated. For example, "a set cannot be processed by two sessions" is abnormal, I should put transaction in the Action method, so that the add method is opened before it enters, And the add method is closed. It should be the result I want. Time is tight, and it is only necessary to wait for the next project to test.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.