Một ứng dụng tôi đang làm việc trên sử dụng Hibernate dành riêng để tìm nạp một loạt các đối tượng liên tục từ cơ sở dữ liệu đến bộ nhớ. Ứng dụng này là làm mới ảnh chụp nhanh trong bộ nhớ này từ cơ sở dữ liệu mọi lúc và sau đó, và đó sẽ là giao tiếp duy nhất với cơ sở dữ liệu.Làm cách nào để tải một tập hợp bản đồ Hibernate thành một bộ không thể sửa đổi được?
Các đối tượng trong bộ nhớ sau đó được sử dụng cho một loạt các phép tính. Các phép tính không được sửa đổi các đối tượng này. Ngoại trừ một số lớp học một nơi nào đó vô tình đã làm, và tôi đã phải dành một ngày săn lùng các lỗi. Bây giờ tôi tự hỏi cách tốt nhất để làm cho toàn bộ cây đối tượng bất biến là gì.
Giả sử hệ thống phân cấp lớp trông như thế này:
public class Building { // persistent entity
private String name; // hibernate-mapped property
private Set<Person> inhabitants; // hibernate-mapped collection
// getters
}
public class Person { // persistent entity
private String name; // hibernate-mapped property
// getters
}
tôi đã ngăn chặn khách hàng truy cập vào cơ sở dữ liệu theo:
- háo hức lấy tất cả các đơn vị và các bộ sưu tập
- đánh dấu tất cả các đơn vị và các bộ sưu tập với
mutable=false
trong ánh xạ Hibernate - không cung cấp bất kỳ phiên bản nào của phiên Hibernate hoặc trạng thái thay đổi g dao phương pháp.
Bây giờ lỗi tôi muốn ngăn chặn là, ai đó vô tình đi building.getInhabitants().clear();
. Tôi có thể nghĩ đến các tùy chọn này:
Getter gói: Hãy
getInhabitants
đầu tiên quấninhabitants
trong một cuộc gọiCollections.unmodifiableSet()
, sau đó trả lại.- Ưu điểm: công việc nhỏ nhất, thêm ít nhất đang
- Nhược điểm: Cảm thấy hacky
lớp Wrapper: Đổi tên
Building
-MutableBuilding
,Person
-MutablePerson
, và cung cấp các lớp học bất biếnBuilding
vàPerson
. Vì ứng dụng của tôi có một điểm chụp rõ ràng, tôi có thể lấy các bản ghi như các đối tượng có thể thay đổi (như tôi làm bây giờ), tạo các bản sao không thay đổi sâu sắc và trình bày cây đối tượng đó cho các máy khách.- Ưu điểm: Thẳng java, không có phép thuật Hibernate. Tôi có thể sử dụng từ khóa yêu thích của mình:
final
- Nhược điểm: Mã khác để viết và duy trì. Ngoài ra, Hibernate sẽ giữ các trường hợp có thể thay đổi trong bộ nhớ?
- Ưu điểm: Thẳng java, không có phép thuật Hibernate. Tôi có thể sử dụng từ khóa yêu thích của mình:
Hibernate lập bản đồ ma thuật: Sử dụng rằng một từ khóa ma thuật để hướng dẫn Hibernate để bọc các bộ sưu tập nó đặt trên các đối tượng thực thể của tôi trong
Collections.unmodifiableSet()
hoặc tương đương.(Lưu ý: Tôi sử dụng một tập tin mapping xml)- Ưu điểm: Elegant, không có mã thêm
- Nhược điểm: từ khóa này có thể không tồn tại
Hibernate mở rộng: Sử dụng rằng một phần mở rộng Hibernate điểm để viết instantiator đối tượng của riêng tôi, và trong đó quấn các thiết lập trong
Collections.unmodifiableSet()
trước khi trả lại nó.- Ưu điểm: Nhiều thanh lịch hơn hack getters tôi
- Nhược điểm: điểm mở rộng này có thể không tồn tại
Ngay bây giờ tôi đang nghiêng về phía # 2, chủ yếu là bởi vì tôi không biết nếu 3 và 4 là có thể.
Cách tốt nhất là gì?
+1 để nhắc tôi lý do tại sao chúng tôi viết getters và setters :-) – KarlP
Điều này dường như là giải pháp tốt nhất. Tôi sẽ phải đi đến các điều khoản với thực tế là các lớp học có thể thay đổi đôi khi được rồi! :) – oksayt