Set up Spring + Hibernate application

Spring và Hibernate là những framework rất phổ biến để làm các enterprise application.Trong bài viết này tôi sẽ thử setup 1 project đơn giản sử dụng 2 framework này step by step

  • Step 1: Tạo maven project và khai báo các dependency trong pom.xml file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ngocnv.com</groupId>
    <artifactId>auction-me</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <spring.framework.version>4.2.5.RELEASE</spring.framework.version>
        <hibernate.version>4.1.9.Final</hibernate.version>
        <mysql.connector.version>5.1.31</mysql.connector.version>
        <jackson.version>2.7.5</jackson.version>
    </properties>

    <dependencies>

        <!-- JUnit testing framework-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>

        <!-- Spring framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>

        <!-- Hibernate Framework -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <!-- MySQL database driver -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.connector.version}</version>
        </dependency>

    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.2</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

Step 2: Config Hibernate JPA

package com.ngocnv.auctionme.config;

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.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;

'@Configuration
'@EnableTransactionManagement
'@PropertySource(value = {"classpath:application.properties", "classpath:application-mysql.properties"})
public class HibernateConfiguration {

    '@Autowired
    private Environment environment;

    '@Bean
    public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean() {
        LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        localContainerEntityManagerFactoryBean.setDataSource(datasource());
        localContainerEntityManagerFactoryBean.setPackagesToScan("com.ngocnv.auctionme.model");
        localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
        localContainerEntityManagerFactoryBean.setJpaProperties(jpaProperties());

        return localContainerEntityManagerFactoryBean;
    }

    '@Bean
    public DataSource datasource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.setDriverClassName"));
        dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
        dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
        dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
        return dataSource;
    }

    private Properties jpaProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        return properties;
    }

    '@Bean
    public HibernateJpaVendorAdapter jpaVendorAdapter() {
        return new HibernateJpaVendorAdapter();
    }

    '@Bean
    public JpaTransactionManager jpaTransactionManager(EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
        jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);
        return jpaTransactionManager;
    }
}

@Configuration: là annotation cho biết đây là file java config và trong file config này có thể định nghĩa các bean, nếu không muốn dùng annotation để config chúng ta có thể sử dụng xml file để config

@Bean: khai báo bean trong spring, các bean sẽ được spring container quản lý life cycle.

@EnableTransactionManagement: enable transaction management của spring-tx

@PropertySource: khai báo các properties file

localContainerEntityManagerFactoryBean() đóng vai trò tạo ra một LocalContainerEntityManagerFactoryBean, sau đó nó sẽ sinh ra một EntityManagerFactory và từ EntityManagerFactory các EntityManager được tạo ra. Các EntityManager cung cấp API cho phép nó quản lý các entity của application trong persistence context mà nó được liên kết tới.

  • Step 3: Config Spring Tạo config file đơn giản, cho phép scan tất cả các component trong project
package com.ngocnv.auctionme.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

`@Configuration
`@ComponentScan(basePackages = {"com.ngocnv.auctionme"})
public class SpringConfiguration {

}

  • Step 4: Add DAO Layer
package com.ngocnv.auctionme.dao;

import com.ngocnv.auctionme.model.Item;

import java.util.List;

public interface ItemDAO {

    public List<Item> getAllItems();
}

package com.ngocnv.auctionme.daoiplm;

import com.ngocnv.auctionme.dao.ItemDAO;
import com.ngocnv.auctionme.model.Item;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

`@Repository
`@Transactional
public class ItemDAOImpl implements ItemDAO {

    `@PersistenceContext
    private EntityManager entityManager;

    `@Override
    public List<Item> getAllItems() {

        List<Item> items = entityManager.createQuery("SELECT c FROM Item c ").getResultList();
        return items;
    }
}

Step 5: Add Service Layer

package com.ngocnv.auctionme.service;

import com.ngocnv.auctionme.model.Item;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by framgia on 22/12/2016.
 * Mostly used as a facade so all controllers have a single point of entry
 */

`@Service
public interface AuctionMeService {

    List<Item> getAllItems();
}
package com.ngocnv.auctionme.serviceiplm;

import com.ngocnv.auctionme.dao.ItemDAO;
import com.ngocnv.auctionme.model.Item;
import com.ngocnv.auctionme.service.AuctionMeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by framgia on 22/12/2016.
 */

`@Service("auctionMeService")
class AuctionMeServiceIpml implements AuctionMeService {

    `@Autowired
    private ItemDAO itemDao;

    `@Override
    public List<Item> getAllItems() {
        return itemDao.getAllItems();
    }
}

  • Step 6: Create Domain Entity Class(POJO)
package com.ngocnv.auctionme.model;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name="item")
public class Item implements Serializable{

    @Id
    @GeneratedValue
    @Column(name="item_id")
    private Integer itemId;

    @Column(name = "name")
    private String name;

    @Column(name = "code")
    private String code;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}

  • Step 7: Create Schema in database
CREATE DATABASE `auctionme`;
USE `auctionme`;

-- item table
CREATE TABLE `item`
(
`item_id` INT(10) AUTO_INCREMENT,
`reg_pgm_id` varchar(50) COLLATE utf8_bin NOT NULL,
`reg_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`upd_pgm_id` varchar(50) COLLATE utf8_bin DEFAULT NULL,
`upd_timestamp` timestamp NULL DEFAULT NULL,
`name` VARCHAR(255) NOT NULL,
`code` VARCHAR(255) NOT NULL,
PRIMARY KEY(`item_id`),
UNIQUE KEY `item_idx01` (`code`) USING BTREE,
KEY `item_idx02` (`name`,`code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
;

insert into item(name, code) values
("frezzer", "code1"),
("airconditioner", "code2"),
("bike", "code3"),
("motor", "code4"),
("fan", "code5"),
("pan", "code6")
;

  • Step 8: Create Properties files application.properties
hibernate.hbm2ddl.auto = validate
hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

application-mysql.properties

jdbc.setDriverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/auctionme
jdbc.username = root
jdbc.password = 123456

  • Step 9: Create Main to run java application logic
package com.ngocnv.auctionme.main;

import com.ngocnv.auctionme.config.SpringConfiguration;
import com.ngocnv.auctionme.model.Item;
import com.ngocnv.auctionme.service.ItemService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;

import java.util.List;

public class Main {

    public static void main(String[] args) {
        AbstractApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        ItemService itemService = (ItemService) context.getBean("itemService");
        List<Item> items = itemService.getAllItems();
        items.forEach(item -> {
            System.out.println(item.getName() + " " + item.getCode());
        });

    }
}

Và đây là kết quả của chương trình:

airconditioner code2
bike code3
fan code5
frezzer code1
motor code4
pan code6