orphanRemoval là gì? Code ví dụ Hibernate orphanRemoval = true.
(Xem thêm: Hướng dẫn tự học Hibernate)
(Xem thêm: Sự khác nhau giữa orphanRemoval = true
với cascadeType = REMOVE
)
OrphanRemoval là gì?
orphanRemoval
là một thuộc tính bên trong annotation @OneToMany
và @OneToOne
.
orphanRemoval
là một đặc tả trong ORM. Nó đánh dấu rằng các phần tử con sẽ bị xóa khi bạn xóa nó khỏi collection của phần tử cha.
Mối quan hệ giữa company và employee là one to many.
@Entity @Table(name = "company") public class Company { //... @OneToMany(fetch = FetchType.LAZY, mappedBy = "company", cascade = {CascadeType.ALL}, orphanRemoval = true) private Set<Employee> listEmployee = new HashSet<>(); //... }
Mối đối tượng company sẽ chứa 1 tập hợp các đối tượng employee, khi một đối tượng employee bị xóa khỏi tập hợp đó thì nó sẽ bị xóa khỏi database.
Code ví dụ orphanRemoval = true
Các công nghệ sử dụng:
CREATE SCHEMA `hibernate-demo` ; CREATE TABLE `hibernate-demo`.`company` ( `id` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR(45) NULL, `address` VARCHAR(255) NULL, PRIMARY KEY (`id`)); CREATE TABLE `hibernate-demo`.`employee` ( `id` INT NOT NULL AUTO_INCREMENT, `company_id` INT NULL, `name` VARCHAR(45) NULL, PRIMARY KEY (`id`), CONSTRAINT `emp-company` FOREIGN KEY (`company_id`) REFERENCES `hibernate-demo`.`company` (`id`));
Quan hệ giữa company và employee là 1-nhiều.
Cấu trúc project
Các thư viện sử dụng
<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>stackjava.com</groupId> <artifactId>HibernateOrphanRemoval</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> <hibernate.version>5.3.6.Final</hibernate.version> </properties> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> </dependencies> </project>
File cấu hình hibernate, kết nối tới MySQL
<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="persistence"> <description>Demo Hibernate OrphanRemoval</description> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <properties> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/hibernate-demo" /> <property name="javax.persistence.jdbc.user" value="root" /> <property name="javax.persistence.jdbc.password" value="admin1234" /> <property name="hibernate.show_sql" value="true" /> </properties> </persistence-unit> </persistence>
Trong ví dụ này mình sử dụng entityManager
nên sẽ khai báo file persistence.xml
nếu các bạn sử dụng hibernateSession
thì có thể khai báo file hibernate.cfg.xml
(Xem lại: Code ví dụ Hibernate EntityManager, EntityManagerFactory)
(Xem lại: Code ví dụ Hibernate Session, SessionFactory)
Các file entities
package stackjava.com.hibernatedemo.entities; import javax.persistence.*; @Entity @Table(name = "employee") public class Employee { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "name") private String name; @ManyToOne @JoinColumn(name = "company_id", nullable = false) private Company company; // getter - setter @Override public String toString() { return "Employee [id=" + id + ", name=" + name + ", company=" + company + "]"; } }
package stackjava.com.hibernatedemo.entities; import java.util.HashSet; import java.util.Set; import javax.persistence.*; @Entity @Table(name = "company") public class Company { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "name") private String name; @OneToMany(fetch = FetchType.LAZY, mappedBy = "company", cascade = {CascadeType.ALL}, orphanRemoval = true) private Set<Employee> listEmployee = new HashSet<>(); // getter - setter @Override public String toString() { return "Company [id=" + id + ", name=" + name + "]"; } }
Mặc định orphanRemoval = false
. Ở đây mình sẽ chuyển thành orphanRemoval = true
Demo Insert
Mình sẽ thực hiện insert 1 company với nhiều employee.
package stackjava.com.hibernatedemo; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import stackjava.com.hibernatedemo.entities.Company; import stackjava.com.hibernatedemo.entities.Employee; public class DemoInsert { public static void main(String[] args) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence"); EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); Company company = new Company(); company.setName("Google"); Employee emp1 = new Employee(); emp1.setName("kai"); emp1.setCompany(company); Employee emp2 = new Employee(); emp2.setName("sena"); emp2.setCompany(company); company.getListEmployee().add(emp1); company.getListEmployee().add(emp2); entityManager.persist(company); entityManager.getTransaction().commit(); System.out.println("-------------------"); System.out.println(company); System.out.println(emp1); System.out.println(emp2); entityManager.close(); entityManagerFactory.close(); } }
Kết quả:
Hibernate: insert into company (name) values (?) Hibernate: insert into employee (company_id, name) values (?, ?) Hibernate: insert into employee (company_id, name) values (?, ?) ------------------- Company [id=4, name=Google] Employee [id=8, name=kai, company=Company [id=4, name=Google]] Employee [id=7, name=sena, company=Company [id=4, name=Google]]
Đối tượng company id = 4 và 2 đối tượng employee có id = 7,8 được lưu vào database.
Demo orphanremoval
Bây giờ mình sẽ lấy đối tượng company vừa tạo ở trên, và xóa đối tượng employee có id = 7 khỏi danh sách các employee của company đó.
package stackjava.com.hibernatedemo; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import stackjava.com.hibernatedemo.entities.Company; public class DemoOrphanRemoval { public static void main(String[] args) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence"); EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); Company company = entityManager.find(Company.class, 7); System.out.println(company); company.getListEmployee().removeIf(employee -> employee.getId() == 7); entityManager.persist(company); entityManager.getTransaction().commit(); entityManager.close(); entityManagerFactory.close(); } }
Kết quả:
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_ from company company0_ where company0_.id=? Company [id=4, name=Google] Hibernate: select listemploy0_.company_id as company_3_1_0_, listemploy0_.id as id1_1_0_, listemploy0_.id as id1_1_1_, listemploy0_.company_id as company_3_1_1_, listemploy0_.name as name2_1_1_ from employee listemploy0_ where listemploy0_.company_id=? Hibernate: delete from employee where id=?
Sau khi remove đối tượng employee có id = 7 khỏi company và thực hiện persist company đó, thì đối tượng company đó sẽ bị xóa khỏi database.
Okay, Done!
Download code ví dụ trên tại đây.
References:
http://mrbool.com/hibernate-framework-orphanremoval-with-hibernate