Trong Jakarta Persistence thì đối tượng EntityManagerFactory là một đối tượng factory chịu trách nhiệm quản lý các cấu hình liên quan đến persistence configuration và tạo ra các EntityManager instances. Việc sử dụng Spring để quản lý đối tượng này sẽ giúp chúng ta rất nhiều trong việc phát triển các ứng dụng Java có sử dụng Jakarta Persistence. Trong bài viết này, mình sẽ hướng dẫn các bạn cách sử dụng Jakarta Persistence với Spring Framework, các bạn nhé!
Đầu tiên, mình sẽ tạo mới một Maven project để làm ví dụ:

Spring framework dependency:
|
1 2 3 4 5 |
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>7.0.10</version> </dependency> |
Để làm việc với Jakarta Persistence, chúng ta cũng cần thêm spring-orm dependency nữa:
|
1 2 3 4 5 |
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>7.0.10</version> </dependency> |
Ở đây, mình sẽ sử dụng Jakarta Persistence với implementation của Hibernate nên mình sẽ thêm Hibernate dependency như sau:
|
1 2 3 4 5 |
<dependency> <groupId>org.hibernate.orm</groupId> <artifactId>hibernate-core</artifactId> <version>7.4.14.Final</version> </dependency> |
MySQL Connector:
|
1 2 3 4 5 |
<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>26.10.0</version> </dependency> |
Để đơn giản, trong ví dụ này, mình chỉ định nghĩa một table chứa thông tin sinh viên với 2 cột như sau:
|
1 2 3 4 5 |
CREATE TABLE `student` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; |
Entity của table Student có nội dung như sau:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
package com.huongdanjava.spring; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.Table; @Table(name = "students") @Entity public class Student { @Id @GeneratedValue private Long id; @Column private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + "]"; } } |
Để làm việc với Jakarta Persistence, chúng ta cần có một tập tin cấu hình persistence.xml cho nó. Các bạn hãy tạo mới tập tin persistence.xml nằm trong thư mục /src/main/resources/META-INF, các bạn nhé!
Nội dung của tập tin này như sau:
|
1 2 3 4 5 6 7 8 9 10 |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <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_3_2.xsd" version="3.2"> <persistence-unit name="springPU" transaction-type="RESOURCE_LOCAL"> <class>com.huongdanjava.spring.Student</class> </persistence-unit> </persistence> |
Các bạn có thể xem thêm về tập tin persistence.xml ở đây.
Bây giờ sẽ là phần quan trọng nhất: khai báo đối tượng EntityManagerFactory trong Spring container.
Trong Spring, hiện tại chúng ta có hai class hỗ trợ cho việc khai báo đối tượng EntityManagerFactory đó là:
- LocalContainerEntityManagerFactoryBean
- LocalEntityManagerFactoryBean
Với class LocalEntityManagerFactoryBean thì tập tin cấu hình của Jakarta Persistence, persistence.xml, thường nằm trong thư mục /src/main/resources/META-INF. Với class LocalContainerEntityManagerFactoryBean thì location của tập tin persistence.xml sẽ linh hoạt hơn. Chúng ta có thể override lại location của nó và việc sử dụng LocalContainerEntityManagerFactoryBean sẽ giúp các bạn có thể khai báo JDBC Datasources linh hoạt hơn nữa.
Mình sẽ sử dụng LocalContainerEntityManagerFactoryBean trong ví dụ này với khai báo cho nó trong Spring container như sau:
|
1 2 3 4 5 6 7 |
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="persistenceUnitName" value="springPU" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> </property> </bean> |
Như các bạn thấy, có 3 thuộc tính mà chúng ta cần phải khai báo cùng với class LocalContainerEntityManagerFactory đó là:
- dataSource: thuộc tính này dùng để khai báo DataSource cho EntityManagerFactory của chúng ta. DataSource ở đây, chúng ta có thể hiểu nôm na là phần quản lý kết nối tới database. Chúng ta có thể khai báo nhiều loại DataSource khác nhau do nhiều tổ chức khác nhau implement interface javax.sql.DataSource.
- persistenceUnitName: đây là tên của Persistence Unit mà chúng ta đã khai báo trong tập tin cấu hình của Jakarta Persistence, persistence.xml.
- jpaVendorAdapter: thuộc tính này dùng để khai báo thư viện chúng ta sẽ sử dụng cho phần implementation của Jakarta Persistence. Trong ví dụ này, mình sử dụng Hibernate nên khai báo là HibernateJpaVendorAdapter. Nếu các bạn sử dụng EclipseLink làm implementation của Jakarta Persistence thì hãy khai báo thuộc tính này là org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter.
Phần dataSource trong ví dụ này mình sẽ sử dụng DriverManagerDataSource với các khai báo như chúng ta làm cho JDBC, như sau:
|
1 2 3 4 5 6 |
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3307/example" /> <property name="username" value="root" /> <property name="password" value="123456" /> </bean> |
OK, vậy là chúng ta đã hoàn thành việc khai báo EntityManagerFactory trong Spring container. Giờ thì sử dụng nó thôi!
Ví dụ của mình như sau:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.huongdanjava.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; public class Application { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml"); EntityManagerFactory emf = (EntityManagerFactory) ac.getBean("entityManagerFactory"); EntityManager em = emf.createEntityManager(); Student student = em.find(Student.class, Long.valueOf(1)); System.out.println(student.getName()); } } |
Hiện tại database của mình đang có dữ liệu như sau:

nên kết quả sẽ là:



độ
anh có fb hay gì ko ạ cho em xin em hỏi chút vấn đề ạ
Khanh Nguyen
Hỏi ở đây nè em https://www.facebook.com/groups/721409674679531/?ref=bookmarks
Hung Pham
Bạn cho mình hỏi là khi khai báo :
Nhưng khi dùng :
EntityManagerFactory emf = (EntityManagerFactory) ac.getBean(“entityManagerFactory”);
Mình xem thì ko thấy mối liên hệ nào giữa LocalContainerEntityManagerFactoryBean và EntityManagerFactory.
làm sao để spring hiểu được như vậy? Thanks!
Khanh Nguyen
Bạn xem như thế nào thế?
thuong_java
anh xem giúp e lỗi này là gì ạ
Error creating bean with name ‘studentDaoImpl’: Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘entityManagerFactory’
Khanh Nguyen
File cấu hình Spring của bạn như thế nào nhỉ?