reset password

REST API Using Spring and Hibernate

3. MySQL and Hibernate

There are many different ways to configure Hibernate with Spring - first of all you can use either JPA or Hibernate Session, and then you have various choices like using hibernate.cfg.xml or not using one, specifying database information in Spring or in Hibernate, creating a data source in Spring or getting one from JNDI, and so on. Here I'll describe the way that I think is the best and the simplest.

1. Install MySQL database server as described here. MySQL 5.5 or above is required for this project. The sample code in the rest of the section is for MySQL 8.0.

Create an empty database called springrest, and run the SQL script springrest-create.sql - it creates several tables and inserts a couple of test users in the database.

2. Add the following dependencies to your project:

  • org.springframework:spring-orm:5.0.9.RELEASE
  • org.hibernate:hibernate-entitymanager:5.3.6.Final
  • mysql:mysql-connector-java:8.0.12
  • org.apache.tomcat:tomcat-jdbc

tomcat-jdbc is a database connection pooling library for Tomcat, and you should choose the version that matches the version of your Tomcat server.

3. Add a file src/main/resources/META-INF/persistence.xml as follows:

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
        http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
    version="2.1">

    <persistence-unit name="springrest">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect" />
        </properties>
    </persistence-unit>

</persistence>

This file provides the information about the JPA Entity Manager provider. Note that because we are using MySQL 8.0, the Hibernate dialect is MySQL8Dialect. If you use MySQL 5.5 or 5.7, it should be MySQL55Dialect or MySQL57Dialect. And for MySQL 5.x, you also need to specify a driver class property:

<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />

4. Add the following to web.xml:   

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>jpaFilter</filter-name>  
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>  
    </filter>  

    <filter-mapping>  
        <filter-name>jpaFilter</filter-name>  
        <url-pattern>/api/*</url-pattern>  
    </filter-mapping>

The ContextLoaderListener will load another Spring bean configuration file, and by default that file is /WEB-INF/applicationContext.xml. This bean configuration file is not absolutely necessary for this step - we could put all the Hibernate/database beans in springrest-servlet.xml, but this file is required later when we add security to the application, and it is customary to put beans that are not related to the web tier in applicationContext.xml as oppose to <dispatcher-servlet-name>-servlet.xml, which is sometimes referred to as the servlet context.

The jpaFilter keeps the entity manager open until after the response is generated; without it Hibernate won't be able to do lazy loading outside the DAO methods.

5. Create a file /WEB-INF/applicationContext.xml as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />

        <property name="url" value="jdbc:mysql://localhost/springrest?allowPublicKeyRetrieval=true&amp;useSSL=false" />
        <property name="username" value="cysun" />
        <property name="password" value="abcd" />
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="springrest" />
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

    <context:annotation-config />

    <tx:annotation-driven />

    <context:component-scan base-package="springrest.model" />

</beans>

It adds four beans: a data source, an entity manager factory, a transaction manager, and an exception translator that translates various SQL/database exceptions into a Spring exception. <context:annotation-config> enables annotations like @Autowired and @PersistenceContext (which is like an @Autowired specifically for entity manager), <tx:annotation-driven> enables annotations like @Transactional, and <context:component-scan> looks for beans under the package springrest.model and its sub-packages.

6. Add the following code to the project:

Run the project and use a browser to open the URL http://localhost:8080/springrest/api/users - you should see a JSON response like the following:

[{"id":1,"username":"admin","enabled":true,"roles":[{"id":1,"name":"ADMIN"}]},{"id":2,"username":"cysun","enabled":true,"roles":[]}]

This page has been viewed 4313 times.