6.1 Quản lý phụ thuộc sâu
Và một số điều hữu ích và thú vị hơn về chú thích @OneToMany và những thứ tương tự. Tất cả đều có 4 tùy chọn thường được sử dụng:
- tầng = CascadeType.ALL
- mồ côiRemoval = true
- tìm nạp = FetchType.LAZY
Bây giờ chúng tôi sẽ phân tích chúng chi tiết hơn. Và chúng ta sẽ bắt đầu với điều thú vị nhất - CascadeType . Tham số này xác định điều gì sẽ xảy ra với các thực thể phụ thuộc nếu chúng ta thay đổi thực thể chính.
Đặc tả JPA có các giá trị sau cho tham số này:
- TẤT CẢ
- KIÊN TRÌ
- HỢP NHẤT
- DI DỜI
- LÀM CHO KHỎE LẠI
- TÁCH
Tuy nhiên, Hibernate mở rộng đặc điểm kỹ thuật này thành ba tùy chọn khác:
- TÁI BẢN
- SAVE_UPDATE
- KHÓA
Tất nhiên, có một sự song song mạnh mẽ với cơ sở dữ liệu và CONSTRANIS của chúng. Tuy nhiên, cũng có sự khác biệt. Hibernate cố gắng che giấu công việc thực sự với cơ sở dữ liệu càng nhiều càng tốt, vì vậy các Cascade Hibernate này chính xác là về các đối tượng Thực thể.
6.2 CascadeType
Tham số tầng mô tả điều gì sẽ xảy ra với các đối tượng phụ thuộc nếu chúng ta thay đổi cha mẹ của chúng (đối tượng chính). Thông thường, tham số này được sử dụng cùng với các chú thích mô tả các phụ thuộc đối tượng:
Ví dụ:
OneToOne(cascade = CascadeType.ALL)
Hoặc như thế này:
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
Nó cũng có thể được viết như một chú thích riêng:
@Cascade({ org.hibernate.annotations.CascadeType.ALL })
Bây giờ hãy nói thêm về ý nghĩa của những chú thích này.
6.3 TẤT CẢ, TUYỆT VỜI, HỢP NHẤT
CascadeType.ALL
có nghĩa là tất cả các hành động mà chúng ta thực hiện với đối tượng cha phải được lặp lại cho các đối tượng phụ thuộc của nó.
CascadeType.PERSIST
có nghĩa là nếu chúng ta lưu đối tượng cha vào cơ sở dữ liệu, thì điều tương tự cũng phải được thực hiện với các đối tượng phụ thuộc của nó. Ví dụ:
@Entity
@Table(name="employee")
class Employee {
@Column(name="id")
public Integer id;
@OneToOne(cascade = CascadeType.PERSIST, mappedBy="task")
private EmployeeTask task;
}
Một ví dụ làm việc với lớp này:
Employee director = new Employee();
EmployeeTask task = new EmployeeTask();
director.task = task;
session.persist(director);
session.flush();
Chúng ta chỉ lưu một đối tượng kiểu Employee, đối tượng phụ thuộc của nó là EmployeeTask sẽ tự động được lưu vào cơ sở dữ liệu.
CascadeType.MERGE
có nghĩa là nếu chúng ta cập nhật đối tượng cha trong cơ sở dữ liệu, thì điều tương tự cũng phải được thực hiện với các đối tượng phụ thuộc của nó.
6.4 XÓA, XÓA, TÁCH
CascadeType.REMOVE
có nghĩa là nếu chúng ta xóa một đối tượng cha trong cơ sở dữ liệu, thì điều tương tự cũng phải được thực hiện với các đối tượng phụ thuộc của nó.
CascadeType.DELETE
cùng nghĩa. Đây là những từ đồng nghĩa. Chỉ từ thông số kỹ thuật khác nhau.
CascadeType.DETACH
có nghĩa là nếu chúng ta xóa đối tượng cha khỏi phiên, thì điều tương tự cũng phải được thực hiện với các đối tượng phụ thuộc của nó. Ví dụ:
@Entity
@Table(name="employee")
class Employee {
@Column(name="id")
public Integer id;
@OneToOne(cascade = CascadeType.DETACH, mappedBy="task")
private EmployeeTask task;
}
Một ví dụ làm việc với lớp này:
Employee director = new Employee();
EmployeeTask task = new EmployeeTask();
director.task = task;
director.task = task;
session.flush();
assertThat(session.contains(director)).isTrue();
assertThat(session.contains(task)).isTrue();
session.detach(director);
assertThat(session.contains(director)).isFalse();
assertThat(session.contains(task)).isFalse();
CascadeType.REFRESH
và CascadeType.SAVE_UPDATE
hoạt động theo cách giống như chúng ta mong đợi - chúng nhân bản các hành động được thực hiện với đối tượng cha sang đối tượng phụ thuộc của nó.
6.5 Tùy chọn loại bỏ trẻ mồ côi
Ngoài ra, đôi khi bạn có thể bắt gặp tham số orphan
. Đây là viết tắt của Loại bỏ trẻ mồ côi. Nó được sử dụng để đảm bảo rằng không có thực thể con nào không có thực thể cha.
OneToOne(orphan = true)
Nếu tham số này được đặt thành true, thì thực thể con sẽ bị xóa nếu nó biến mấttất cả các liên kết. Nó không hoàn toàn giống như Cascade.REMOVE
.
Bạn có thể gặp tình huống trong đó một số thực thể mẹ đề cập đến một con. Sau đó, có lợi là nó không bị xóa cùng với việc xóa thực thể mẹ, nhưng chỉ khi tất cả các tham chiếu đến nó bị vô hiệu hóa.
Giả sử bạn có một lớp học:
@Entity
@Table(name="user")
class Employee {
@Column(name="id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL, orphan = true)
@JoinColumn(name = "employee_id")
private Set<EmployeeTask> tasks = new HashSet<EmployeeTask>();
}
Employee director = session.find(Employee.class, 4);
EmployeeTask task = director.tasks.get(0);
director.tasks.remove(task)
session.persist(director);
session.flush();
Đối tượng EmployeeTask sẽ bị xóa vì không còn tham chiếu nào đến nó. Đồng thời, không ai xóa đối tượng mẹ.
6.6 tùy chọn tìm nạp
Tùy chọn tìm nạp cho phép bạn kiểm soát cách các đối tượng phụ thuộc được tải. Nó thường nhận một trong hai giá trị:
FetchType.LAZY
FetchType.EAGER
Đây là một chủ đề rất thú vị với nhiều cạm bẫy khác nhau, vì vậy tốt hơn là tôi nên nói về nó trong một bài giảng riêng.
GO TO FULL VERSION