diff --git a/persistence-modules/README.md b/persistence-modules/README.md
index 2fbaf25f2f..f6189392b1 100644
--- a/persistence-modules/README.md
+++ b/persistence-modules/README.md
@@ -5,7 +5,6 @@
### Relevant Articles:
- [Introduction to Hibernate Search](http://www.baeldung.com/hibernate-search)
-- [Bootstrapping Hibernate 5 with Spring](http://www.baeldung.com/hibernate-5-spring)
- [Introduction to Lettuce – the Java Redis Client](http://www.baeldung.com/java-redis-lettuce)
- [A Guide to Jdbi](http://www.baeldung.com/jdbi)
- [Pessimistic Locking in JPA](http://www.baeldung.com/jpa-pessimistic-locking)
diff --git a/persistence-modules/spring-persistence-simple/README.md b/persistence-modules/spring-persistence-simple/README.md
index 2fcd05e84a..aabbb3c248 100644
--- a/persistence-modules/spring-persistence-simple/README.md
+++ b/persistence-modules/spring-persistence-simple/README.md
@@ -5,6 +5,7 @@
### Relevant Articles:
- [A Guide to JPA with Spring](https://www.baeldung.com/the-persistence-layer-with-spring-and-jpa)
+- [Bootstrapping Hibernate 5 with Spring](http://www.baeldung.com/hibernate-5-spring)
### Eclipse Config
diff --git a/persistence-modules/spring-persistence-simple/pom.xml b/persistence-modules/spring-persistence-simple/pom.xml
index e624af4ea6..4057db8033 100644
--- a/persistence-modules/spring-persistence-simple/pom.xml
+++ b/persistence-modules/spring-persistence-simple/pom.xml
@@ -32,7 +32,16 @@
-
+
+ org.hibernate
+ hibernate-core
+ ${hibernate.version}
+
+
+ javax.transaction
+ jta
+ ${jta.version}
+
org.hibernate
hibernate-entitymanager
@@ -55,6 +64,12 @@
${h2.version}
+
+ org.apache.tomcat
+ tomcat-dbcp
+ ${tomcat-dbcp.version}
+
+
@@ -104,6 +119,8 @@
5.4.2.Final
6.0.6
2.1.6.RELEASE
+ 9.0.0.M26
+ 1.1
21.0
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/bootstrap/BarHibernateDAO.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/bootstrap/BarHibernateDAO.java
new file mode 100644
index 0000000000..5fc932b256
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/bootstrap/BarHibernateDAO.java
@@ -0,0 +1,39 @@
+package com.baeldung.hibernate.bootstrap;
+
+import com.baeldung.hibernate.bootstrap.model.TestEntity;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public abstract class BarHibernateDAO {
+
+ @Autowired
+ private SessionFactory sessionFactory;
+
+ public TestEntity findEntity(int id) {
+
+ return getCurrentSession().find(TestEntity.class, 1);
+ }
+
+ public void createEntity(TestEntity entity) {
+
+ getCurrentSession().save(entity);
+ }
+
+ public void createEntity(int id, String newDescription) {
+
+ TestEntity entity = findEntity(id);
+ entity.setDescription(newDescription);
+ getCurrentSession().save(entity);
+ }
+
+ public void deleteEntity(int id) {
+
+ TestEntity entity = findEntity(id);
+ getCurrentSession().delete(entity);
+ }
+
+ protected Session getCurrentSession() {
+ return sessionFactory.getCurrentSession();
+ }
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/bootstrap/HibernateConf.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/bootstrap/HibernateConf.java
new file mode 100644
index 0000000000..150e3778af
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/bootstrap/HibernateConf.java
@@ -0,0 +1,61 @@
+package com.baeldung.hibernate.bootstrap;
+
+import com.google.common.base.Preconditions;
+import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.orm.hibernate5.HibernateTransactionManager;
+import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.sql.DataSource;
+import java.util.Properties;
+
+@Configuration
+@EnableTransactionManagement
+@PropertySource({ "classpath:persistence-h2.properties" })
+public class HibernateConf {
+
+ @Autowired
+ private Environment env;
+
+ @Bean
+ public LocalSessionFactoryBean sessionFactory() {
+ final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
+ sessionFactory.setDataSource(dataSource());
+ sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate.bootstrap.model" });
+ sessionFactory.setHibernateProperties(hibernateProperties());
+
+ return sessionFactory;
+ }
+
+ @Bean
+ public DataSource dataSource() {
+ final BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
+ dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
+ dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
+ dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
+
+ return dataSource;
+ }
+
+ @Bean
+ public PlatformTransactionManager hibernateTransactionManager() {
+ final HibernateTransactionManager transactionManager = new HibernateTransactionManager();
+ transactionManager.setSessionFactory(sessionFactory().getObject());
+ return transactionManager;
+ }
+
+ private final Properties hibernateProperties() {
+ final Properties hibernateProperties = new Properties();
+ hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
+ hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
+
+ return hibernateProperties;
+ }
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/bootstrap/HibernateXMLConf.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/bootstrap/HibernateXMLConf.java
new file mode 100644
index 0000000000..b3e979478f
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/bootstrap/HibernateXMLConf.java
@@ -0,0 +1,24 @@
+package com.baeldung.hibernate.bootstrap;
+
+import com.google.common.base.Preconditions;
+import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ImportResource;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.orm.hibernate5.HibernateTransactionManager;
+import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.sql.DataSource;
+import java.util.Properties;
+
+@Configuration
+@EnableTransactionManagement
+@ImportResource({ "classpath:hibernate5Configuration.xml" })
+public class HibernateXMLConf {
+
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/bootstrap/model/TestEntity.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/bootstrap/model/TestEntity.java
new file mode 100644
index 0000000000..cae41db831
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/bootstrap/model/TestEntity.java
@@ -0,0 +1,29 @@
+package com.baeldung.hibernate.bootstrap.model;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class TestEntity {
+
+ private int id;
+
+ private String description;
+
+ @Id
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+}
diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/hibernate5Config.xml b/persistence-modules/spring-persistence-simple/src/main/resources/hibernate5Config.xml
new file mode 100644
index 0000000000..bbb61cb3e0
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/resources/hibernate5Config.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+ ${hibernate.hbm2ddl.auto}
+ ${hibernate.dialect}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/hibernate5Configuration.xml b/persistence-modules/spring-persistence-simple/src/main/resources/hibernate5Configuration.xml
new file mode 100644
index 0000000000..cb6cf0aa5c
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/resources/hibernate5Configuration.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+ ${hibernate.hbm2ddl.auto}
+ ${hibernate.dialect}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/persistence-mysql.properties b/persistence-modules/spring-persistence-simple/src/main/resources/persistence-mysql.properties
new file mode 100644
index 0000000000..b3cfd31f46
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/main/resources/persistence-mysql.properties
@@ -0,0 +1,13 @@
+# jdbc.X
+jdbc.driverClassName=com.mysql.cj.jdbc.Driver
+jdbc.url=jdbc:mysql://localhost:3306/spring_hibernate5_01?createDatabaseIfNotExist=true
+jdbc.eventGeneratedId=tutorialuser
+jdbc.pass=tutorialmy5ql
+
+# hibernate.X
+hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
+hibernate.show_sql=false
+hibernate.hbm2ddl.auto=create-drop
+
+# envers.X
+envers.audit_table_suffix=_audit_log
diff --git a/persistence-modules/spring-persistence-simple/src/test/java/com/baeldung/hibernate/bootstrap/HibernateBootstrapIntegrationTest.java b/persistence-modules/spring-persistence-simple/src/test/java/com/baeldung/hibernate/bootstrap/HibernateBootstrapIntegrationTest.java
new file mode 100644
index 0000000000..c41423643a
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/test/java/com/baeldung/hibernate/bootstrap/HibernateBootstrapIntegrationTest.java
@@ -0,0 +1,185 @@
+package com.baeldung.hibernate.bootstrap;
+
+import com.baeldung.hibernate.bootstrap.model.TestEntity;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.annotation.Commit;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+import org.springframework.test.context.transaction.TestTransaction;
+import org.springframework.transaction.annotation.Transactional;
+
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertTrue;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { HibernateConf.class })
+@Transactional
+public class HibernateBootstrapIntegrationTest {
+
+ @Autowired
+ private SessionFactory sessionFactory;
+
+ @Test
+ public void whenBootstrapHibernateSession_thenNoException() {
+
+ Session session = sessionFactory.getCurrentSession();
+
+ TestEntity newEntity = new TestEntity();
+ newEntity.setId(1);
+ session.save(newEntity);
+
+ TestEntity searchEntity = session.find(TestEntity.class, 1);
+
+ Assert.assertNotNull(searchEntity);
+ }
+
+ @Test
+ public void whenProgrammaticTransactionCommit_thenEntityIsInDatabase() {
+ assertTrue(TestTransaction.isActive());
+
+ //Save an entity and commit.
+ Session session = sessionFactory.getCurrentSession();
+
+ TestEntity newEntity = new TestEntity();
+ newEntity.setId(1);
+ session.save(newEntity);
+
+ TestEntity searchEntity = session.find(TestEntity.class, 1);
+
+ Assert.assertNotNull(searchEntity);
+ assertTrue(TestTransaction.isFlaggedForRollback());
+
+ TestTransaction.flagForCommit();
+ TestTransaction.end();
+
+ assertFalse(TestTransaction.isFlaggedForRollback());
+ assertFalse(TestTransaction.isActive());
+
+ //Check that the entity is still there in a new transaction,
+ //then delete it, but don't commit.
+ TestTransaction.start();
+
+ assertTrue(TestTransaction.isFlaggedForRollback());
+ assertTrue(TestTransaction.isActive());
+
+ session = sessionFactory.getCurrentSession();
+ searchEntity = session.find(TestEntity.class, 1);
+
+ Assert.assertNotNull(searchEntity);
+
+ session.delete(searchEntity);
+ session.flush();
+
+ TestTransaction.end();
+
+ assertFalse(TestTransaction.isActive());
+
+ //Check that the entity is still there in a new transaction,
+ //then delete it and commit.
+ TestTransaction.start();
+
+ session = sessionFactory.getCurrentSession();
+ searchEntity = session.find(TestEntity.class, 1);
+
+ Assert.assertNotNull(searchEntity);
+
+ session.delete(searchEntity);
+ session.flush();
+
+ assertTrue(TestTransaction.isActive());
+
+ TestTransaction.flagForCommit();
+ TestTransaction.end();
+
+ assertFalse(TestTransaction.isActive());
+
+ //Check that the entity is no longer there in a new transaction.
+ TestTransaction.start();
+
+ assertTrue(TestTransaction.isActive());
+
+ session = sessionFactory.getCurrentSession();
+ searchEntity = session.find(TestEntity.class, 1);
+
+ Assert.assertNull(searchEntity);
+ }
+
+ @Test
+ @Commit
+ public void givenTransactionCommitDefault_whenProgrammaticTransactionCommit_thenEntityIsInDatabase() {
+ assertTrue(TestTransaction.isActive());
+
+ //Save an entity and commit.
+ Session session = sessionFactory.getCurrentSession();
+
+ TestEntity newEntity = new TestEntity();
+ newEntity.setId(1);
+ session.save(newEntity);
+
+ TestEntity searchEntity = session.find(TestEntity.class, 1);
+
+ Assert.assertNotNull(searchEntity);
+ assertFalse(TestTransaction.isFlaggedForRollback());
+
+ TestTransaction.end();
+
+ assertFalse(TestTransaction.isFlaggedForRollback());
+ assertFalse(TestTransaction.isActive());
+
+ //Check that the entity is still there in a new transaction,
+ //then delete it, but don't commit.
+ TestTransaction.start();
+
+ assertFalse(TestTransaction.isFlaggedForRollback());
+ assertTrue(TestTransaction.isActive());
+
+ session = sessionFactory.getCurrentSession();
+ searchEntity = session.find(TestEntity.class, 1);
+
+ Assert.assertNotNull(searchEntity);
+
+ session.delete(searchEntity);
+ session.flush();
+
+ TestTransaction.flagForRollback();
+ TestTransaction.end();
+
+ assertFalse(TestTransaction.isActive());
+
+ //Check that the entity is still there in a new transaction,
+ //then delete it and commit.
+ TestTransaction.start();
+
+ session = sessionFactory.getCurrentSession();
+ searchEntity = session.find(TestEntity.class, 1);
+
+ Assert.assertNotNull(searchEntity);
+
+ session.delete(searchEntity);
+ session.flush();
+
+ assertTrue(TestTransaction.isActive());
+
+ TestTransaction.end();
+
+ assertFalse(TestTransaction.isActive());
+
+ //Check that the entity is no longer there in a new transaction.
+ TestTransaction.start();
+
+ assertTrue(TestTransaction.isActive());
+
+ session = sessionFactory.getCurrentSession();
+ searchEntity = session.find(TestEntity.class, 1);
+
+ Assert.assertNull(searchEntity);
+ }
+
+}
diff --git a/persistence-modules/spring-persistence-simple/src/test/java/com/baeldung/hibernate/bootstrap/HibernateXMLBootstrapIntegrationTest.java b/persistence-modules/spring-persistence-simple/src/test/java/com/baeldung/hibernate/bootstrap/HibernateXMLBootstrapIntegrationTest.java
new file mode 100644
index 0000000000..5b811ad576
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/test/java/com/baeldung/hibernate/bootstrap/HibernateXMLBootstrapIntegrationTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.hibernate.bootstrap;
+
+import com.baeldung.hibernate.bootstrap.model.TestEntity;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.transaction.annotation.Transactional;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { HibernateXMLConf.class })
+@Transactional
+public class HibernateXMLBootstrapIntegrationTest {
+
+ @Autowired
+ private SessionFactory sessionFactory;
+
+ @Test
+ public void whenBootstrapHibernateSession_thenNoException() {
+
+ Session session = sessionFactory.getCurrentSession();
+
+ TestEntity newEntity = new TestEntity();
+ newEntity.setId(1);
+ session.save(newEntity);
+
+ TestEntity searchEntity = session.find(TestEntity.class, 1);
+
+ Assert.assertNotNull(searchEntity);
+ }
+
+}