hibernate4 事务使用注意以下几点;
1.在web.xml中配置openSessionInViewFilter,这个也是解决使用hibernate4 Hibernate4 No Session found for current thread
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.在spring配置文件中
配置datasource
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${jdbc_url}" />
<property name="username">
<value>${jdbc_username}</value>
</property>
<property name="password" value="${jdbc_password}" />
<property name="filters">
<value>stat</value>
</property>
<property name="maxActive">
<value>20</value>
</property>
<property name="initialSize">
<value>1</value>
</property>
<property name="maxWait">
<value>60000</value>
</property>
<property name="minIdle">
<value>1</value>
</property>
<property name="timeBetweenEvictionRunsMillis">
<value>60000</value>
</property>
<property name="minEvictableIdleTimeMillis">
<value>300000</value>
</property>
<property name="validationQuery">
<value>SELECT 'x'</value>
</property>
<property name="testWhileIdle">
<value>true</value>
</property>
<property name="testOnBorrow">
<value>false</value>
</property>
<property name="testOnReturn">
<value>false</value>
</property>
<property name="poolPreparedStatements">
<value>true</value>
</property>
<property name="maxOpenPreparedStatements">
<value>20</value>
</property>
</bean>
配置sessionfactory
<!-- 配置hibernate session工厂 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<!-- <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> -->
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.current_session_context_class">
org.springframework.orm.hibernate4.SpringSessionContext
</prop>
</props>
</property>
<!-- 自动扫描注解方式配置的hibernate类文件 -->
<property name="packagesToScan">
<list>
<value>com.whxd.cn.**</value>
</list>
</property>
<!-- 自动扫描hbm方式配置的hibernate文件和.hbm文件 -->
<!-- <property name="mappingDirectoryLocations"> <list> <value>classpath:sy/hbm</value> </list> </property> -->
</bean>
配置事务管理器
<!-- 配置事务管理器 -->
<bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
拦截器方式配置事物
<!-- 拦截器方式配置事物 -->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- <tx:method name="add*" /> <tx:method name="save*" /> <tx:method name="update*" /> <tx:method name="modify*" /> <tx:method name="edit*" /> <tx:method name="delete*" /> <tx:method name="remove*" /> <tx:method name="repair" /> <tx:method name="deleteAndRepair" /> <tx:method name="get*" propagation="SUPPORTS" /> <tx:method name="find*" propagation="SUPPORTS" /> <tx:method name="load*" propagation="SUPPORTS" /> <tx:method name="search*" propagation="SUPPORTS" /> <tx:method name="datagrid*" propagation="SUPPORTS" /> <tx:method name="*" propagation="SUPPORTS" /> -->
<!-- 指定哪些方法需要加入事务,这里懒惰一下全部加入,可以使用通配符来只加入需要的方法 -->
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="get*" propagation="REQUIRED" read-only="true"/>
<tx:method name="query*" propagation="REQUIRED" read-only="true"/>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="transactionPointcut" expression="execution(* com.whxd.cn.openjweb..*.*(..))" />
<aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
</aop:config>
其中拦截匹配的表达式中
expression="execution(* com.whxd.cn.openjweb..*.*(..))
从左往右
第一个*表示方法返回的类型
第二个* 表示类名
第三个*表示方法名
openjweb..表示下的所有子包
(..)表示任意参数
同时要是需要多个拦截表达式可以使用||或者 or
例如expression="(execution(* com.whxd.cn.openjweb..*.*(..))) or (execution(* com.whxd.cn.core..*.*(..))) "
特别重要的一点,要是serviceImpl有父类的话一定也要包含在匹配的表达式中
及时按照上面的操作了,也可能出现可以查询和删除,但是增加或者修改不可以同步到数据库
我个人省了个懒法,手动刷新了session,就是在service方法执行结束的时候刷新session
// hibernate4 增加了事务,自己不将数据提交到数据库,只能自己动手了。目前没有找到好的办法处理
dBSupportService.getDefaultDao().getThreadLocalSession().flush();
提醒一下,不要再dao层使用session.flush()这样事务就不起作用了