diff --git a/pom.xml b/pom.xml
index 10897d2899..2881ae714b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -348,6 +348,13 @@
provided
true
+
+ org.springframework
+ spring-orm
+ 3.1.1.RELEASE
+ provided
+ true
+
org.springframework
spring-ibatis
diff --git a/src/test/java/com/alibaba/druid/TestHibernateCRUDWithTransactional.java b/src/test/java/com/alibaba/druid/TestHibernateCRUDWithTransactional.java
new file mode 100644
index 0000000000..8a64ad357f
--- /dev/null
+++ b/src/test/java/com/alibaba/druid/TestHibernateCRUDWithTransactional.java
@@ -0,0 +1,12 @@
+package com.alibaba.druid;
+
+import junit.framework.TestCase;
+
+/**
+ * @author yinheli
+ * @date 2012-11-26 下午11:35
+ */
+public class TestHibernateCRUDWithTransactional extends TestCase {
+
+
+}
diff --git a/src/test/java/com/alibaba/druid/bvt/hibernate/HibernateCRUDTest.java b/src/test/java/com/alibaba/druid/bvt/hibernate/HibernateCRUDTest.java
new file mode 100644
index 0000000000..2bf0f7bb95
--- /dev/null
+++ b/src/test/java/com/alibaba/druid/bvt/hibernate/HibernateCRUDTest.java
@@ -0,0 +1,204 @@
+package com.alibaba.druid.bvt.hibernate;
+
+import com.alibaba.druid.bvt.hibernate.entity.Sample;
+import com.alibaba.druid.pool.DruidDataSource;
+import junit.framework.TestCase;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Properties;
+
+/**
+ * @author yinheli
+ * @date 2012-11-26 下午11:41
+ */
+public class HibernateCRUDTest extends TestCase {
+
+ private static final Logger log = LoggerFactory.getLogger(HibernateCRUDTest.class);
+
+ private DruidDataSource dataSource;
+
+ private SessionFactory sessionFactory;
+
+ @Override
+ public void setUp() throws Exception {
+ /*init dataSource*/
+ dataSource = new DruidDataSource();
+ dataSource.setUrl("jdbc:h2:file:~/.h2/HibernateCRUDTest;AUTO_SERVER=TRUE");
+ dataSource.setUsername("sa");
+ dataSource.setPassword("");
+ dataSource.setDefaultAutoCommit(false);
+
+ /*init sessionFactory*/
+ LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
+ factoryBean.setDataSource(dataSource);
+
+ Properties prop = new Properties();
+ prop.put("hibernate.show_sql", "true");
+ //prop.put("hibernate.format_sql", "true");
+ prop.put("hibernate.hbm2ddl.auto", "create");
+ prop.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
+ factoryBean.setHibernateProperties(prop);
+ factoryBean.setAnnotatedClasses(new Class>[]{Sample.class});
+
+ try {
+ factoryBean.afterPropertiesSet();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ sessionFactory = factoryBean.getObject();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ sessionFactory.close();
+ }
+
+ private void doCreate(Session session) {
+ Sample sample = new Sample();
+ sample.setId(1L);
+ sample.setDesc("sample");
+ sample.setCreateTime(new Date());
+ session.save(sample);
+ }
+
+ private void doGet(Session session) {
+ Sample sample = (Sample) session.get(Sample.class, 1L);
+ log.debug("**sample:{}", sample);
+ assert sample != null;
+ }
+
+ private void doUpdate(Session session) {
+ Sample sample = (Sample) session.get(Sample.class, 1L);
+ assert sample != null;
+ sample.setDesc("update sample");
+ sample.setUpdateTime(new Date());
+ session.update(sample);
+ }
+
+ private void doDelete(Session session) {
+ Sample sample = (Sample) session.get(Sample.class, 1L);
+ assert sample != null;
+ session.delete(sample);
+ }
+
+ /*-------- test start --------*/
+
+ public void test_create() {
+ Session session = null;
+ try {
+ session = sessionFactory.openSession();
+ doCreate(session);
+ } finally {
+ if (session != null){
+ session.flush();
+ session.close();
+ }
+ }
+ }
+
+ public void test_get() {
+ Session session = null;
+ try {
+ session = sessionFactory.openSession();
+ doCreate(session);
+ doGet(session);
+ } finally {
+ if (session != null){
+ session.flush();
+ session.close();
+ }
+ }
+ }
+
+ public void test_update() {
+ Session session = null;
+ try {
+ session = sessionFactory.openSession();
+ doCreate(session);
+ doUpdate(session);
+ } finally {
+ if (session != null){
+ session.flush();
+ session.close();
+ }
+ }
+ }
+
+ public void test_delete() {
+ Session session = null;
+ try {
+ session = sessionFactory.openSession();
+ doCreate(session);
+ doDelete(session);
+ } finally {
+ if (session != null){
+ session.flush();
+ session.close();
+ }
+ }
+ }
+
+ public void test_transactional_create() {
+ Session session = null;
+ Transaction tran = null;
+ try {
+ session = sessionFactory.openSession();
+ tran = session.beginTransaction();
+ doCreate(session);
+ } finally {
+ if (tran != null) {
+ tran.commit();
+ }
+ if (session != null){
+ session.flush();
+ session.close();
+ }
+ }
+ }
+
+ public void test_transactional_update() {
+ Session session = null;
+ Transaction tran = null;
+ try {
+ session = sessionFactory.openSession();
+ tran = session.beginTransaction();
+ doCreate(session);
+ doUpdate(session);
+ } finally {
+ if (tran != null) {
+ tran.commit();
+ }
+ if (session != null){
+ session.flush();
+ session.close();
+ }
+ }
+ }
+
+ public void test_transactional_delete() {
+ Session session = null;
+ Transaction tran = null;
+ try {
+ session = sessionFactory.openSession();
+ tran = session.beginTransaction();
+ doCreate(session);
+ doDelete(session);
+ } finally {
+ if (tran != null) {
+ tran.commit();
+ }
+ if (session != null){
+ session.flush();
+ session.close();
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/alibaba/druid/bvt/hibernate/entity/Sample.java b/src/test/java/com/alibaba/druid/bvt/hibernate/entity/Sample.java
new file mode 100644
index 0000000000..8f5baa1dcc
--- /dev/null
+++ b/src/test/java/com/alibaba/druid/bvt/hibernate/entity/Sample.java
@@ -0,0 +1,75 @@
+package com.alibaba.druid.bvt.hibernate.entity;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author yinheli
+ */
+@Entity
+@Table(name = "SAMPLE")
+public class Sample implements Serializable {
+
+ @Id
+ private Long id;
+
+ private String name;
+
+ private String desc;
+
+ private Date createTime;
+
+ private Date updateTime;
+
+ public Date getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Date createTime) {
+ this.createTime = createTime;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Date getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(Date updateTime) {
+ this.updateTime = updateTime;
+ }
+
+ @Override
+ public String toString() {
+ return "Sample{" +
+ "createTime=" + createTime +
+ ", id=" + id +
+ ", name='" + name + '\'' +
+ ", desc='" + desc + '\'' +
+ ", updateTime=" + updateTime +
+ '}';
+ }
+}
diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties
index 425c169e0c..dde6eef30d 100644
--- a/src/test/resources/log4j.properties
+++ b/src/test/resources/log4j.properties
@@ -17,6 +17,7 @@ log4j.appender.FILE.layout.ConversionPattern=%d [%-5p] %c\:%x%L - %m%n
log4j.category.com=DEBUG
log4j.category.com.mchange=ERROR
log4j.category.org.springframework=ERROR
+log4j.category.org.hibernate=ERROR
log4j.category.org.apache.commons=ERROR
log4j.category.org.apache.catalina=ERROR
log4j.category.org.apache.struts.chain=ERROR