In this article, we will make a Hello World app which will demonstrate basic CRUD operations with Hibernate. We’ll be using the latest Java configurations for the project.

Hibernate is a complete solution for the persistence module in a Java project. It handles the application interaction with the database, leaving the developer free to concentrate more on business logic and solving complex problems.

We’ll start with a simple “Hello World” app before moving on to more complex things later on.

Maven Dependency

Let us start by adding the appropriate Maven dependencies to the project’s pom.xml.

<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-dbcp</artifactId> <version>8.0.23</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.1.0.Final</version> </dependency>

Making model entities

To persist, we need a model entity which needs to be stored in the database. For this example, we’ll be using a User object. Let’s design a simple entity:

package com.discoversdk.entities; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String name; private String address; // standard setters and getters }

Hibernate applications define persistent classes that are mapped to database tables. The class above is one of these persistent classes.

This example uses Integer for the type of the identifier attribute, but this isn’t a requirement. Hibernate allows virtually anything for the identifier type. It is worth making note of some annotations we have used in this example:

@Entity : This annotation marks this model class as a persistent class and will make a table in the database with the same name as the class .

@Id : This annotation marks the Integer id as a unique identifier or popularly known as, the Primary Key in the table.

@GeneratedValue ( strategy = GenerationType . AUTO) : With this, values for an identifier will be generated automatically according to the data type it holds.

It is important to make standard Javabeans getters and setter methods in this model, without which Hibernate won’t work.

Configure the Database in Java

The first step to creating a Java based configuration project for Hibernate is configuring the database using only java. Let’s take a look at that.

First, create a plain text file named ‘application.properties’ with the following content:

#DB properties:

jdbc.datasource.driver=com.mysql.jdbc.Driver jdbc.datasource.url=jdbc:mysql://localhost:3306/hellohibernate jdbc.datasource.username=root jdbc.datasource.password=root!

#Hibernate Configuration:

hibernate.hbm2ddl.auto=update hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.show_sql=true jdbc.datasource.entity.package=com.discoversdk.entities

Next, we need to put these properties to use in our DatabaseConfig class. Let’s have a look at the class here:

package com.discoversdk.config; import org.hibernate.SessionFactory; 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.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean; import org.springframework.orm.hibernate4.HibernateTemplate; import org.springframework.orm.hibernate4.HibernateTransactionManager; import javax.annotation.Resource; import javax.sql.DataSource; import java.util.Properties; @Configuration @PropertySource("classpath:application.properties") public class DatabaseConfig { @Resource private Environment env; @Bean public DataSource getDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(env.getProperty("jdbc.datasource.driver")); dataSource.setUrl(env.getProperty("jdbc.datasource.url")); dataSource.setUsername(env.getProperty("jdbc.datasource.username")); dataSource.setPassword(env.getProperty("jdbc.datasource.password")); return dataSource; } @Bean @Autowired public HibernateTemplate getHibernateTemplate(SessionFactory sessionFactory) { return new HibernateTemplate(sessionFactory); } @Bean public AnnotationSessionFactoryBean getSessionFactory() { AnnotationSessionFactoryBean asfb = new AnnotationSessionFactoryBean(); asfb.setDataSource(getDataSource()); asfb.setHibernateProperties(getHibernateProperties()); asfb.setPackagesToScan(env.getProperty("jdbc.datasource.entity.package")); return asfb; } @Bean public Properties getHibernateProperties() { Properties properties = new Properties(); properties.put("hibernate.dialect", env.getProperty("hibernate.dialect")); properties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql")); properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); return properties; } @Bean @Autowired public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) { HibernateTransactionManager htm = new HibernateTransactionManager(); htm.setSessionFactory(sessionFactory); return htm; } }

Hibernate has enough information to generate all the SQL statements needed to insert, update, delete, and retrieve instances of the User class. We no longer need to write these SQL statements by hand.

First up in the configuration file above are the database connection settings. We need to tell Hibernate which database JDBC driver we’re using and how to connect to the database with a URL, username, and password. We set a Dialect, so that Hibernate knows which SQL variation it has to generate to talk to our database; dozens of dialects are packaged with Hibernate so just take a look at the Hibernate API documentation to get a full list.

There are some properties we omitted like:

hibernate.c3p0.min_size = 5

This is the minimum number of JDBC connections that C3P0 keeps ready at all times.

hibernate.c3p0.max_size = 20

This is the maximum number of connections in the pool. An exception is thrown at runtime if this number is exhausted.

hibernate.c3p0.timeout = 300

We specify the timeout period (in this case, 300 seconds) after which an idle connection is removed from the pool.

hibernate.c3p0.max_statements = 50

A maximum of 50 prepared statements will be cached. Caching of prepared statements is essential for best performance with Hibernate.

hibernate.c3p0.idle_test_period = 3000

This is the idle time in seconds before a connection is automatically validated.

For our AppConfig class,

package com.discoversdk.config; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.core.io.ClassPathResource; @Configuration @Import({DatabaseConfig.class}) public class AppConfig { @Bean public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer() { PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); ppc.setLocation(new ClassPathResource("application.properties")); ppc.setIgnoreUnresolvablePlaceholders(true); return ppc; } }

Define Service class

For our UserService class which will handle accessing the database, here is the class:

package com.discoversdk.service; import com.discoversdk.entities.User; import com.discoversdk.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserService { @Autowired private UserRepository userRepository; public List<User> getAllUsers() { return this.userRepository.getAllUsers(); } public Integer createUser(User user) { return this.userRepository.createUser(user); } }

Define Repository class

For our UserRepository class which will handle accessing the database, here is the class:

package com.discoversdk.repository; import com.discoversdk.entities.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate4.HibernateTemplate; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Transactional @Repository public class UserRepository { @Autowired private HibernateTemplate hibernateTemplate; public List<User> getAllUsers() { return this.hibernateTemplate.loadAll(User.class); } public Integer createUser(User user) { User mergeUser = this.hibernateTemplate.merge(user); return mergeUser.getId(); } }

Finally let’s write our main class to put all this to use:

package com.discoversdk; import com.discoversdk.entities.User; import com.discoversdk.service.UserService; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import java.util.List; public class HibernateMain { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); //This will load the configured components UserService, UserRepository, ctx.scan("com.discoversdk"); ctx.refresh(); System.out.println(ctx); UserService userService = ctx.getBean("userService", UserService.class); List<User> allUser = userService.getAllUsers(); for (User u : allUser) { System.out.println(u); } User user = new User(null, "Shubham Aggarwal", "Delhi"); Integer id = userService.createUser(user); System.out.println("Newly created User ID = " + id); allUser = userService.getAllUsers(); for (User u : allUser) { System.out.println(u); } } }

Session

A Hibernate Session is many things at once. It’s a single-threaded non-shared object that represents a particular unit of work with the database. It has the persistence manager API we call to load and store objects. (The Session internals consist of a queue of SQL statements that need to be synchronized with the database at some point and a map of managed persistence instances that are monitored by the Session.)

Transaction

This Hibernate API can be used to set transaction boundaries programmatically, but it’s optional (transaction boundaries aren’t). Other choices are JDBC transaction demarcation, the JTA interface, or container-managed transactions with EJBs.

Conclusion

In this article, we configured Hibernate using a 100% Java configuration and made use of good templating practices. All of this can be found on this Github project which is a maven based project so it should be easy to run.

Be sure to stop by DiscoverSDK.com for more Java SDKs.