diff --git a/spring-hibernate5/pom.xml b/spring-hibernate5/pom.xml
index e3309ff10b..dac43c4dd3 100644
--- a/spring-hibernate5/pom.xml
+++ b/spring-hibernate5/pom.xml
@@ -120,6 +120,12 @@
hsqldb
${hsqldb.version}
+
+
+ mysql
+ mysql-connector-java
+ ${mysql-connector-java.version}
+
com.h2database
@@ -167,7 +173,7 @@
- 4.3.5.RELEASE
+ 4.3.10.RELEASE
1.10.6.RELEASE
@@ -177,7 +183,8 @@
5.2.10.Final
- 8.5.15
+ 8.0.7-dmr
+ 9.0.0.M26
1.1
2.3.4
1.4.195
diff --git a/spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java b/spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java
new file mode 100644
index 0000000000..f1ad30b090
--- /dev/null
+++ b/spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java
@@ -0,0 +1,86 @@
+package com.baeldung.hibernate.manytomany.model;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinTable;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "Employee")
+public class Employee implements Serializable {
+ @Id
+ @Column(name = "employee_id")
+ @GeneratedValue
+ private Long employeeId;
+
+ @Column(name = "first_name")
+ private String firstName;
+
+ @Column(name = "last_name")
+ private String lastName;
+
+ @ManyToMany(cascade = { CascadeType.ALL })
+ @JoinTable(
+ name = "Employee_Project",
+ joinColumns = { @JoinColumn(name = "employee_id") },
+ inverseJoinColumns = { @JoinColumn(name = "project_id") }
+ )
+ Set projects = new HashSet();
+
+
+ public Employee() {
+ super();
+ }
+
+ public Employee(String firstName, String lastName) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public Employee(String firstName, String lastName, Set projects) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.projects = projects;
+ }
+
+
+ public Long getEmployeeId() {
+ return employeeId;
+ }
+
+ public void setEmployeeId(Long employeeId) {
+ this.employeeId = employeeId;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public Set getProjects() {
+ return projects;
+ }
+
+ public void setProjects(Set projects) {
+ this.projects = projects;
+ }
+}
diff --git a/spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java b/spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java
new file mode 100644
index 0000000000..d6c049f33e
--- /dev/null
+++ b/spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java
@@ -0,0 +1,61 @@
+package com.baeldung.hibernate.manytomany.model;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "Project")
+public class Project implements Serializable {
+
+ @Id
+ @Column(name = "project_id")
+ @GeneratedValue
+ private Long projectId;
+
+ @Column(name = "title")
+ private String title;
+
+ @ManyToMany(mappedBy = "projects")
+ private Set employees = new HashSet();
+
+ public Project() {
+ super();
+ }
+
+ public Project(String title) {
+ this.title = title;
+ }
+
+ public Long getProjectId() {
+ return projectId;
+ }
+
+ public void setProjectId(Long projectId) {
+ this.projectId = projectId;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public Set getEmployees() {
+ return employees;
+ }
+
+ public void setEmployees(Set employees) {
+ this.employees = employees;
+ }
+
+
+}
diff --git a/spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java b/spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java
new file mode 100644
index 0000000000..5f489dd027
--- /dev/null
+++ b/spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java
@@ -0,0 +1,41 @@
+package com.baeldung.hibernate.manytomany.util;
+
+import org.hibernate.SessionFactory;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.service.ServiceRegistry;
+import com.baeldung.hibernate.manytomany.model.Employee;
+import com.baeldung.hibernate.manytomany.model.Project;
+
+public class HibernateUtil {
+ private static SessionFactory sessionFactory;
+
+ private static SessionFactory buildSessionFactory() {
+ try {
+ // Create the SessionFactory from hibernate-annotation.cfg.xml
+ Configuration configuration = new Configuration();
+ configuration.addAnnotatedClass(Employee.class);
+ configuration.addAnnotatedClass(Project.class);
+ configuration.configure("manytomany.cfg.xml");
+ System.out.println("Hibernate Annotation Configuration loaded");
+
+ ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties())
+ .build();
+ System.out.println("Hibernate Annotation serviceRegistry created");
+
+ SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
+
+ return sessionFactory;
+ } catch (Throwable ex) {
+ System.err.println("Initial SessionFactory creation failed." + ex);
+ ex.printStackTrace();
+ throw new ExceptionInInitializerError(ex);
+ }
+ }
+
+ public static SessionFactory getSessionFactory() {
+ if (sessionFactory == null)
+ sessionFactory = buildSessionFactory();
+ return sessionFactory;
+ }
+}
diff --git a/spring-hibernate5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java b/spring-hibernate5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java
new file mode 100644
index 0000000000..6f359054b6
--- /dev/null
+++ b/spring-hibernate5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java
@@ -0,0 +1,70 @@
+package com.baeldung.manytomany.spring;
+
+import java.util.Properties;
+import javax.sql.DataSource;
+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.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
+import org.springframework.orm.hibernate4.HibernateTransactionManager;
+import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+
+
+@Configuration
+@EnableTransactionManagement
+@PropertySource({ "classpath:persistence-mysql.properties" })
+@ComponentScan({ "com.baeldung.hibernate.manytomany" })
+public class PersistenceConfig {
+
+ @Autowired
+ private Environment env;
+
+ @Bean
+ public LocalSessionFactoryBean sessionFactory() {
+ final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
+ sessionFactory.setDataSource(restDataSource());
+ sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate.manytomany" });
+ sessionFactory.setHibernateProperties(hibernateProperties());
+
+ return sessionFactory;
+ }
+
+ @Bean
+ public DataSource restDataSource() {
+ final BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
+ dataSource.setUrl(env.getProperty("jdbc.url"));
+ dataSource.setUsername(env.getProperty("jdbc.user"));
+ dataSource.setPassword(env.getProperty("jdbc.pass"));
+
+ return dataSource;
+ }
+
+ @Bean
+ public PlatformTransactionManager hibernateTransactionManager() {
+ final HibernateTransactionManager transactionManager = new HibernateTransactionManager();
+ transactionManager.setSessionFactory(sessionFactory().getObject());
+ return transactionManager;
+ }
+
+ @Bean
+ public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
+ return new PersistenceExceptionTranslationPostProcessor();
+ }
+
+ 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"));
+ hibernateProperties.setProperty("hibernate.show_sql", "true");
+
+ return hibernateProperties;
+ }
+}
diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java b/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java
new file mode 100644
index 0000000000..d619807b64
--- /dev/null
+++ b/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.manytomany.dao;
+
+import com.baeldung.hibernate.manytomany.model.Employee;
+import com.baeldung.persistence.dao.common.IOperations;
+
+public interface IEmployeeDao extends IOperations{
+
+}
diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java b/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java
new file mode 100644
index 0000000000..4a55714f8d
--- /dev/null
+++ b/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.manytomany.dao;
+
+import com.baeldung.hibernate.manytomany.model.Project;
+import com.baeldung.persistence.dao.common.IOperations;
+
+public interface IProjectDao extends IOperations{
+
+}
diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java b/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java
new file mode 100644
index 0000000000..b062c00ff9
--- /dev/null
+++ b/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java
@@ -0,0 +1,16 @@
+package com.baeldung.persistence.manytomany.dao.impl;
+
+import org.springframework.stereotype.Repository;
+import com.baeldung.hibernate.manytomany.model.Employee;
+import com.baeldung.persistence.dao.common.AbstractHibernateDao;
+import com.baeldung.persistence.manytomany.dao.IEmployeeDao;
+
+@Repository
+public class EmployeeDao extends AbstractHibernateDao implements IEmployeeDao {
+
+ public EmployeeDao() {
+ super();
+
+ setClazz(Employee.class);
+ }
+}
diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java b/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java
new file mode 100644
index 0000000000..772026fbc1
--- /dev/null
+++ b/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java
@@ -0,0 +1,17 @@
+package com.baeldung.persistence.manytomany.dao.impl;
+
+import org.springframework.stereotype.Repository;
+import com.baeldung.hibernate.manytomany.model.Project;
+import com.baeldung.persistence.dao.common.AbstractHibernateDao;
+import com.baeldung.persistence.manytomany.dao.IProjectDao;
+
+
+@Repository
+public class ProjectDao extends AbstractHibernateDao implements IProjectDao {
+
+ public ProjectDao() {
+ super();
+
+ setClazz(Project.class);
+ }
+}
diff --git a/spring-hibernate5/src/main/resources/manytomany.cfg.xml b/spring-hibernate5/src/main/resources/manytomany.cfg.xml
new file mode 100644
index 0000000000..8a10fc1580
--- /dev/null
+++ b/spring-hibernate5/src/main/resources/manytomany.cfg.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+ com.mysql.jdbc.Driver
+
+
+ buddhinisam123
+
+
+ jdbc:mysql://localhost:3306/spring_hibernate_many_to_many
+
+
+ root
+
+
+ org.hibernate.dialect.MySQLDialect
+
+
+ thread
+
+ true
+
+
diff --git a/spring-hibernate5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java b/spring-hibernate5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java
new file mode 100644
index 0000000000..61d821e85e
--- /dev/null
+++ b/spring-hibernate5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java
@@ -0,0 +1,53 @@
+package com.baeldung.hibernate.manytomany;
+
+
+import java.util.HashSet;
+import java.util.Set;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.junit.After;
+import org.junit.Before;
+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.test.context.support.AnnotationConfigContextLoader;
+import com.baeldung.hibernate.manytomany.model.Employee;
+import com.baeldung.hibernate.manytomany.model.Project;
+import com.baeldung.manytomany.spring.PersistenceConfig;
+
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = {PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class)
+public class HibernateManyToManyAnnotationJavaConfigMainIntegrationTest {
+
+ @Autowired
+ private SessionFactory sessionFactory;
+
+ private Session session;
+
+
+ @Before
+ public final void before() {
+ session = sessionFactory.openSession();
+ session.beginTransaction();
+ }
+
+ @After
+ public final void after() {
+ session.getTransaction().commit();
+ session.close();
+ }
+
+ @Test
+ public final void whenEntitiesAreCreated_thenNoExceptions() {
+ Set projects = new HashSet();
+ projects.add(new Project("IT Project"));
+ projects.add(new Project("Networking Project"));
+ session.persist(new Employee("Peter", "Oven", projects));
+ session.persist(new Employee("Allan", "Norman", projects));
+ }
+
+}
diff --git a/spring-hibernate5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationXMLConfigMainIntegrationTest.java b/spring-hibernate5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationXMLConfigMainIntegrationTest.java
new file mode 100644
index 0000000000..5308134fac
--- /dev/null
+++ b/spring-hibernate5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationXMLConfigMainIntegrationTest.java
@@ -0,0 +1,84 @@
+package com.baeldung.hibernate.manytomany;
+
+import static org.junit.Assert.assertNotNull;
+import static junit.framework.TestCase.assertEquals;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import com.baeldung.hibernate.manytomany.util.HibernateUtil;
+import com.baeldung.hibernate.manytomany.model.Employee;
+import com.baeldung.hibernate.manytomany.model.Project;
+
+
+public class HibernateManyToManyAnnotationXMLConfigMainIntegrationTest {
+ private static SessionFactory sessionFactory;
+
+ private Session session;
+
+
+ @BeforeClass
+ public static void beforeTests() {
+ sessionFactory = HibernateUtil.getSessionFactory();
+ }
+
+ @Before
+ public void setUp() {
+ session = sessionFactory.openSession();
+ session.beginTransaction();
+ }
+
+
+ @Test
+ public void givenSession_checkIfDatabaseIsPopulated() {
+ Employee employee1 = new Employee("Peter", "Oven");
+ Set projects = new HashSet();
+ projects = employee1.getProjects();
+ int noProjects = projects.size();
+ assertEquals(0,noProjects);
+ Project project1 = new Project("IT Project");
+ assertNotNull(project1);
+ projects.add(project1);
+ Project project2 = new Project("Networking Project");
+ assertNotNull(project2);
+ projects.add(project2);
+ employee1.setProjects(projects);
+ assertNotNull(employee1);
+ Employee employee2 = new Employee("Allan", "Norman");
+ employee2.setProjects(projects);
+ assertNotNull(employee2);
+
+ session.persist(employee1);
+ session.persist(employee2);
+ session.getTransaction().commit();
+ session.close();
+
+ session = sessionFactory.openSession();
+ session.beginTransaction();
+ @SuppressWarnings("unchecked")
+ List projectList = session.createQuery("FROM Project").list();
+ assertNotNull(projectList);
+ @SuppressWarnings("unchecked")
+ List employeeList = session.createQuery("FROM Employee").list();
+ assertNotNull(employeeList);
+ }
+
+
+ @After
+ public void tearDown() {
+ session.getTransaction().commit();
+ session.close();
+ }
+
+ @AfterClass
+ public static void afterTests() {
+ sessionFactory.close();
+ }
+
+}