In this tutorial we will show how you can create an Hibernate 6 application using annotations. For this purpose we will use a basic Maven archetype and we will enhance so that it uses Hibernate dependencies and MySQL as database.
Project setup
There can be several starting points for setting up an Hibernate projects with Maven. The bare bones approach could be using the maven-archetype-quickstart and then updating the pom.xml file with all Hibernate dependencies.
Provided that you have successfully installed Maven, let’s create the project HibernateExample with the following command:
mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart -DgroupId=com.mastertheboss -DartifactId=HibernateExample -Dversion=1.0.0
Adding Hibernate Dependencies
Next, we will add Hibernate core and MySQL Dependencies which you need to build our project:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate-version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency>
Replace hibernate-version with the correct version of Hibernate. For your reference, the latest version of Hibernate is version 7.0.0.Beta1 ( As of October 2024 )
You can optionally include additional libraries to use Hikari Connection pool. Also, you should add libraries to display logs when running the application:
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.9</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>2.0.9</version> </dependency>
Coding the Model
Firstly, we need to define our Model. We will use two Classes: a Department Class and an Employee Class which are in a One To Many Relation:
.
Here’s the Department class:
package com.mastertheboss.domain; import java.util.ArrayList; import java.util.List; import javax.persistence.*; @Entity @Table public class Department { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(mappedBy="department",cascade=CascadeType.PERSIST) private List<Employee> employees = new ArrayList<Employee>(); // Getters/Setters and Constructors omitted for the sake of brevity } }
Then, this is is the Employee class:
package com.mastertheboss.domain; import javax.persistence.*; @Entity @Table public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @ManyToOne private Department department; // Getters/Setters and Constructors omitted for the sake of brevity }
Adding a Class to manage Hibernate SessionFactory
In Hibernate, the SessionFactory
is a crucial component responsible for creating and managing Hibernate Session
instances. It is a thread-safe, immutable, and heavyweight object that is typically instantiated once during the application’s startup process.
In order to manage the Hibernate SessionFactory
we will create an Utility class named HibernateUtil:
package com.mastertheboss.util; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } public static void shutdown() { // Close caches and connection pools getSessionFactory().close(); } }
Testing the Hibernate Project
Finally, we will add a Java Main Class which will test inserting Employees and Departments:
public class App { private static final Logger logger = LoggerFactory.getLogger(App.class); public static void main(String[] args) { Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); Department department = new Department("java"); session.persist(department); session.persist(new Employee("Jakab Gipsz",department)); session.persist(new Employee("Captain Nemo",department)); session.getTransaction().commit(); Query q = session.createQuery("From Employee ", Employee.class); List<Employee> resultList = q.list(); System.out.println("num of employees:" + resultList.size()); for (Employee next : resultList) { System.out.println("next employee: " + next); } } }
Adding the Hibernate Configuration
In order to work, this application requires an hibernate.cfg.xml file which needs to be placed into the resources/META-INF folder of your application. For the purpose of our example, we will suppose you have an active MySQL DB on localhost with a mysqldb database:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.url">jdbc:mysql://localhost:3306/mysqldb</property> <property name="connection.username">root</property> <property name="connection.password">my-secret-pw</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="format_sql">true</property> <property name="hbm2ddl.auto">create-drop</property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size">1</property> <property name="current_session_context_class">thread</property> <mapping class="com.mastertheboss.domain.Employee" /> <mapping class="com.mastertheboss.domain.Department" /> </session-factory> </hibernate-configuration>
Please be aware that by using the property hbm2ddl.auto to create, the tables will be dropped and re-created each time that the application is deployed. Consider using another strategy if you are holding data in your tables.
Here’s how your project source should look like:
src └── main ├── java │ └── com │ └── mastertheboss │ ├── App.java │ ├── domain │ │ ├── Department.java │ │ └── Employee.java │ └── util │ └── HibernateUtil.java └── resources └── hibernate.cfg.xml
Make sure your Maven project contains the following plugin configuration to start the com.mastertheboss.App Class.
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <configuration> <mainClass>com.mastertheboss.App</mainClass> <cleanupDaemonThreads>false</cleanupDaemonThreads> </configuration> </plugin>
With that in place, you can test your application with:
mvn install exec:java
Hint
You don’t have MySQL installed to test this example? then you can use Docker to run it:
docker run -d -p 3306:3306 -e MYSQL_DATABASE="mysqldb" -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql
Conclusion
In conclusion, this Hibernate 6 tutorial with Maven has provided a comprehensive overview of utilizing Hibernate in your Java projects. By leveraging the power of Maven, the popular build automation tool, you can easily manage dependencies and streamline the development process.
Source code available here: https://github.com/fmarchioni/mastertheboss/tree/master/hibernate/HibernateExample