Hibernate整合进spring

简介:

1 零丁应用hibernate处理惩罚事物

底本只用hibernate开辟,从而可以省了DAO层实现数据库接见和跨数据库,也可以对代码进行更好的封装,当我们web中零丁应用hibernate时,我们须要零丁的处理惩罚hibernate的事务,我是应用filter来对事务进行把握的:

零丁应用hibernate应用filter进行事务把握:

HibernateSessionFilter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public  class  HibernateSessionFilter implements  Filter {
  
     public  void  destroy() {
         
     }
  
     public  void  doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws  IOException,
             ServletException {
         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();
         }
     }
  
     public  void  init(FilterConfig arg0) throws  ServletException {
     }
  
  }

web.xml

1
2
3
4
5
6
7
8
9
10
<filter>
   <filter-name>hibernateSessionFilter</filter-name>
   <filter- class > syx.jpkc.filter.HibernateSessionFilter</filter- class >
  </filter>
  <filter-mapping>
   <filter-name>hibernateSessionFilter</filter-name>
   <url-pattern>*.syx</url-pattern>
   <url-pattern>*.jsp</url-pattern>
   <url-pattern>*.eve</url-pattern>
  </filter-mapping>

&#160;

我首要在servlet(*.syx,*.eve)和jsp页面(没用struts)须要和数据库操纵,所以须要应用事务处理惩罚。

上方我们还用到了一个 HibernateUtils的小对象类,首要为了获取Session对象和一点优化:

HibernateUitls.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public  class  HibernateUtils {
     private  static  Map<Thread, Session> sessionMap;
     private  static  SessionFactory sessionFactory;
     static  {
         sessionMap = new  HashMap<Thread, Session>();
         sessionFactory = new  Configuration().configure().buildSessionFactory();
     }
  
     /**
      * can only use in web filter, beause it should remove and clear resources
      * @return
      */
     public  static  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  static  Session getCurrentSession() {
         return  sessionMap.get(Thread.currentThread());
     }
  
     public  static  void  closeAndRemoveSession() {
         System.out.println(Thread.currentThread().getStackTrace()[ 1 ]+ " run in "  + new  Date()); //
         Session session = sessionMap.remove(Thread.currentThread());
         if  (session != null ) {
             session.close();
         }
     }
  }

&#160;

2 hibernate整合进spring后的事物处理惩罚

spring事物处理惩罚的体式格式有很多,详见:http://www.blogjava.net/robbie/archive/2009/04/05/264003.html

介绍常用的:

spring annotation声明式的事务经管

1) 事物处理惩罚层?

比如保存一个User,可以在Service层和DAOImpl层实现:

1
2
3
4
5
6
7
8
9
10
11
12
public  void  save(User u) {
     userDAO.save(u);
  }
  
  public  void  save(User u) {
     System.out.println( "save user :"  + this );
     Session s = sessionFactory.openSession();
     s.beginTransaction();
     s.save(u);
     s.getTransaction().commit();
     s.close();
  }

假如我们还有个日记记录,没保存一个User对象,要写入日记进入数据库。

而save(log) 和 save(user)必须处在同一事务中,所以不克不及放在DAOImpl层,事务处理惩罚在Service层。

2) 一般的事务处理惩罚

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Session sess = factory.openSession();
  Transaction tx;
  try  {
      tx = sess.beginTransaction();
      //do some work
      //save(user);
      //save(log);
      ...
      tx.commit();
  } catch  (Exception e) {
      if  (tx!= null ) tx.rollback();
      throw  e;
  } finally  {
      sess.close();
  }

并且要在实现层中的save()办法中也要参加事务处理惩罚,若是出呈现异常要throws给上级处理惩罚!

并且实现层中的session必须应用openCurrentSession()获得。

1
2
Session s = sessionFactory.getCurrentSession();
  s.save(u);

3) spring annotation事务处理惩罚

Beans.xml中引入响应的xml定名空间和响应设备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
http: //www.springframework.org/schema/tx
http: //www.springframework.org/schema/tx/spring-tx-3.0.xsd
<tx:annotation-driven transaction-manager= "txManager" />
<bean id= "txManager"  class = "org.springframework.orm.hibernate3.HibernateTransactionManager" >
   <property name= "sessionFactory"  ref= "sessionFactory"  />
</bean>
<bean id= "dataSource"
     class = "org.apache.commons.dbcp.BasicDataSource"
     destroy-method= "close" >
     <property name= "driverClassName"
         value= "¥{jdbc.driverClassName}"  />
     <property name= "url"  value= "¥{jdbc.url}"  />
     <property name= "username"  value= "¥{jdbc.username}"  />
     <property name= "password"  value= "¥{jdbc.password}"  />
</bean>
<bean id= "sessionFactory"
     class = "org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >
     <property name= "dataSource"  ref= "dataSource"  />
     <property name= "annotatedClasses" >
         <list>
             <value>com.syx.model.User</value>
             <value>com.syx.model.Log</value>
         </list>
     </property>
     <property name= "hibernateProperties" >
         <props>
             <prop key= "hibernate.dialect" >org.hibernate.dialect.MySQLDialect</prop>
             <prop key= "hibernate.show_sql" > true </prop>
             <prop key= "current_session_context_class" >thread</prop>
         </props>
     </property>
</bean>
Save办法:
public  void  save(User u) {
     Session s = sessionFactory.getCurrentSession();
     s.save(u);
}
public  void  save(Log log) {
     Session s = sessionFactory.getCurrentSession();
     s.save(log);
}
Service层处理惩罚:
@Component( "userService"
public  class  UserService {
     UserDAO userDAO = null ;
     LogDAO logDAO = null ;
     
     public  LogDAO getLogDAO() {
         return  logDAO;
     }
     @Resource(name= "logDAOMySQLImpl"
     public  void  setLogDAO(LogDAO logDAO) {
         this .logDAO = logDAO;
     }
     @Transactional
     public  void  save(User u) {
         userDAO.save(u);
         Log log = new  Log();
         log.setMsg(u.getName() + " saved in "  + new  Date());
         logDAO.save(log);
     }
     public  UserDAO getUserDAO() {
         return  userDAO;
     }
     @Resource(name= "userDAOMySQLImpl"
     public  void  setUserDAO(UserDAO userDAO) {
         this .userDAO = userDAO;
     }
}

4) @Transactional详解

什么时辰rollback

运行期异常,非运行期异常不会触发rollback

必须uncheck (没有catch)

不管什么异常,只要你catch了,spring就会放弃经管

事务传播特点:propagation_required

propagation 默认是 REQUIRED ,意思是有我们就用现成的,没的我们就发明一个,其他具体见文档

spring xml声明式的事务经管

设备景象和annotation版本一致,只是在用@Transactional处注释调用,在beans.xml中参加如下设备:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- spring tranception xml config -->
     < aop:config >
         < aop:pointcut  id="serviceOperation"
             expression="execution(* com.syx.service..*.*(..))" />
         < aop:advisor  pointcut-ref="serviceOperation" advice-ref="txAdvice" />
     </ aop:config >
  
     < tx:advice  id="txAdvice"  transaction-manager="txManager">
         < tx:attributes >
             < tx:method  name="getUser" read-only="true" />
             < tx:method  name="save" /> <!-- 相当于在上方切面pointcut@Transactional结果 -->
         </ tx:attributes >
     </ tx:advice >
1
< span  style="font-size: medium; font-weight: bold;">3 hibernateTemplate.getSessionFactory().getCurrentSession()</ span >

我们应用spring和hibernate连络,操纵数据库最常用可能是HibernateTemplate,HibernateTemplate中集成了很多应用的办法,可惜的是没的createQuery办法,也许我们应用hibernate的时辰喜好应用Query,我们可能会封装hibernateTemplate.getSessionFactory().getCurrentSession()办法获得Session,session创建Query,这是一个办法,但你应当会获得异常 “createQuery without an active transaction”,因为应用hibernateTemplate.getSessionFactory().getCurrentSession(),你是应用的hibernate的事务经管,而你指望spring经管的事物是hibernateTemplate,所以你会提示没有打开事务的异常,解决办法:1)应用hibernate事务处理惩罚,就像上方零丁应用hibernate一样,但这也许不是你想要的。2)应用hibernateTemplate的HibernateCallBack回调:

1
2
3
4
5
6
7
8
return hibernateTemplate.executeWithNativeSession(
     new HibernateCallback< List <T>>() {
     public  List< T > doInHibernate(Session session)
     throws HibernateException, SQLException {
         return session.createQuery
         ("FROM " + entityClass.getName() + " WHERE id IN (:ids)")//
         .setParameterList("ids", idList).list();
     }

&#160;

实际上hibernateTemplate中封装的find办法也很强大,若是谙练应用完全可以调换createQuery的。

备注:

若是呈现异常:对同一个凑集处理惩罚不克不及应用2个session,这是因为getCurrentSession办法失足,导致打开一个新的session,搜检设备文件,若是应用tomcat+spring+hibernate 设备hibernate.current_session_context_class 最好为thread,固然支撑jta,设备斗劲麻烦,并且jta支撑多个sessionFactory,即可以跨数据库,斗劲强大!

若是hibernate+spring呈现session没有提友情况,应当是你让spring负责事务处理惩罚,而你有应用了hibernate的session,从而离开spring事务处理惩罚,即没的begintransaction和commit之类的操纵了。



本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/archive/2013/02/26/2933102.html,如需转载请自行联系原作者

相关文章
|
2月前
|
Java 数据库连接 API
Java 8 + 特性及 Spring Boot 与 Hibernate 等最新技术的实操内容详解
本内容涵盖Java 8+核心语法、Spring Boot与Hibernate实操,按考试考点分类整理,含技术详解与代码示例,助力掌握最新Java技术与应用。
90 3
|
XML JSON Java
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
本文介绍了如何使用IntelliJ IDEA和Maven搭建一个整合了Struts2、Spring4、Hibernate4的J2EE项目,并配置了项目目录结构、web.xml、welcome.jsp以及多个JSP页面,用于刷新和学习传统的SSH框架。
451 0
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
|
Java 数据库连接 数据库
Spring Data JPA 与 Hibernate 之区别
【8月更文挑战第21天】
335 0
|
前端开发 Java 关系型数据库
在Spring3 MVC中五步配置集成注解方式Hibernate3
在Spring3 MVC中五步配置集成注解方式Hibernate3
93 3
|
Java 数据库连接 数据库
如何在Spring Boot中集成Hibernate
如何在Spring Boot中集成Hibernate
|
XML Java Apache
必知的技术知识:HHS整合(Struts2+Spring+Hibernate)
必知的技术知识:HHS整合(Struts2+Spring+Hibernate)
129 0
|
SQL Java 数据库连接
jpa、hibernate、spring-data-jpa、jdbcTemplate
jpa、hibernate、spring-data-jpa、jdbcTemplate
170 1
|
Java 数据库连接 Spring
spring配合hibernate报错:sessionFactory or hibernateTemplate is required
根据你的具体情况,检查上述步骤中的一个或多个,以确定为何出现“sessionFactory or hibernateTemplate is required”错误,并采取相应的措施进行修复。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
116 0
|
网络安全
ssh(Spring+Spring mvc+hibernate)——updateEmp.jsp
ssh(Spring+Spring mvc+hibernate)——updateEmp.jsp
|
网络安全
ssh(Spring+Spring mvc+hibernate)——updateDept.jsp
ssh(Spring+Spring mvc+hibernate)——updateDept.jsp