Cấu hình Hibernate trong ứng dụng Spring

Giới thiệu

Bài viết này tập trung vào việc tích hợp Hibernate vào một ứng dụng dựa trên Spring Framework. Chúng ta sẽ không đi sâu vào cách sử dụng Hibernate cơ bản, chẳng hạn như cấu hình ánh xạ đối tượng-cơ sở dữ liệu qua XML hay các thao tác CRUD chi tiết. Thay vào đó, mục tiêu là hướng dẫn cách cấu hình Spring để quản lý và sử dụng Hibernate một cách hiệu quả trong môi trường Spring. Trong Spring, việc quản lý vòng đời của Hibernate (như tạo và hủy Session) được thực hiện tự động, giúp đơn giản hóa đáng kể quá trình phát triển.

Session và SessionFactory trong Hibernate

Để sử dụng Hibernate, cần hiểu hai khái niệm cốt lõi:
  • Session: Là giao diện chính để tương tác với cơ sở dữ liệu. Nó cung cấp các phương thức để thực hiện các thao tác持久化 (lưu trữ) như thêm, sửa, xóa, truy vấn.
  • SessionFactory: Là một đối tượng nặng, chịu trách nhiệm tạo và quản lý các đối tượng Session. Thông thường, chỉ có một thể hiện của SessionFactory cho toàn bộ ứng dụng.
Trong bối cảnh Spring, Spring Container sẽ quản lý đối tượng SessionFactory, và chúng ta sẽ lấy Session từ SessionFactory này để thực hiện các thao tác dữ liệu.

Cấu hình Hibernate trong ngữ cảnh Spring

Spring cung cấp các bean để tạo và cấu hình SessionFactory. Dưới đây là các cách phổ biến:

2.1. Hibernate 3 với ánh xạ XML (LocalSessionFactoryBean)

Đối với Hibernate phiên bản 3 và sử dụng file ánh xạ XML, chúng ta sử dụng `LocalSessionFactoryBean`.
import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;

@Bean
public LocalSessionFactoryBean hibernateSessionFactory(DataSource dataSource) {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource);
    // Chỉ định vị trí của các file ánh xạ XML
    sessionFactory.setMappingLocations(new String[]{"classpath:hibernate/mapping/product.hbm.xml"});
    
    Properties hibernateProps = new Properties();
    hibernateProps.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
    hibernateProps.setProperty("hibernate.show_sql", "true");
    sessionFactory.setHibernateProperties(hibernateProps);
    
    return sessionFactory;
}

2.2. Hibernate 3 với chú thích (AnnotationSessionFactoryBean)

Đối với Hibernate 3 và sử dụng chú thích (annotations) để ánh xạ, chúng ta sử dụng `AnnotationSessionFactoryBean`.
import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;

@Bean
public AnnotationSessionFactoryBean annotationSessionFactory(DataSource dataSource) {
    AnnotationSessionFactoryBean sessionFactory = new AnnotationSessionFactoryBean();
    sessionFactory.setDataSource(dataSource);
    // Quét các package chứa các lớp được chú thích
    sessionFactory.setAnnotatedClasses(new Class[]{com.example.model.Product.class});
    
    Properties hibernateProps = new Properties();
    hibernateProps.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
    hibernateProps.setProperty("hibernate.show_sql", "true");
    sessionFactory.setHibernateProperties(hibernateProps);
    
    return sessionFactory;
}

2.3. Hibernate 4 (với XML hoặc chú thích)

Đối với Hibernate 4, dù sử dụng XML hay chú thích, chúng ta đều sử dụng `LocalSessionFactoryBean`.
import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;

@Bean
public LocalSessionFactoryBean modernSessionFactory(DataSource dataSource) {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource);
    // Quét các package chứa các lớp được chú thích
    sessionFactory.setPackagesToScan(new String[]{"com.example.model"});
    
    Properties hibernateProps = new Properties();
    hibernateProps.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
    hibernateProps.setProperty("hibernate.show_sql", "true");
    sessionFactory.setHibernateProperties(hibernateProps);
    
    return sessionFactory;
}

Sử dụng Hibernate để thực hiện CRUD

Sau khi có SessionFactory, chúng ta có thể inject nó vào một repository để thực hiện các thao tác dữ liệu.
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class ProductRepositoryImpl implements ProductRepository {

    @Autowired
    private SessionFactory sessionFactory;

    // Lấy Session hiện tại, thường được quản lý bởi Spring Transaction Manager
    public Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    public void save(Product product) {
        getCurrentSession().save(product);
    }
}

Vai trò của @Repository

Annotation `@Repository` không chỉ đánh dấu một lớp là một thành phần truy cập dữ liệu mà còn có một chức năng quan trọng khác. Khi trong ngữ cảnh Spring có cấu hình `PersistenceExceptionTranslationPostProcessor`, nó sẽ tự động thêm một bộ xử lý ngoại lệ (advisor) vào tất cả các bean được đánh dấu bằng `@Repository`. Điều này giúp chuyển đổi các ngoại lệ cụ thể của nền tảng (ví dụ: `SQLException`) thành các ngoại lệ truy cập dữ liệu không kiểm tra (unchecked) của Spring, giúp mã nguồn trở nên sạch sẽ và dễ bảo trì hơn.
@Bean
public BeanPostProcessor exceptionTranslationProcessor() {
    return new PersistenceExceptionTranslationPostProcessor();
}

Thẻ: Spring Framework hibernate orm Java

Đăng vào ngày 25 tháng 6 lúc 05:55