Danh sách các bang

Và bây giờ niềm vui bắt đầu. Chúng ta sẽ nghiên cứu các trạng thái của đối tượng Entity. Bạn phải trả tiền cho mọi thứ và cả việc sử dụng Hibernate nữa. Bạn không nghĩ rằng học HQL là một mức giá như vậy? Không, cuộc sống phức tạp hơn một chút.

Nếu bạn có một số loại đối tượng Thực thể mà bạn có thể lưu vào cơ sở dữ liệu bằng Hibernate, thì theo quan điểm của Hibernate, đối tượng này có thể có bốn trạng thái:

  • Tạm thời
  • Liên tục (hoặc được quản lý)
  • tách ra
  • LOẠI BỎ

Và để bạn quan tâm, tôi sẽ thêm hình ảnh này vào bài giảng này:

Tạm thời

Trên thực tế, mọi thứ đơn giản hơn nhiều so với vẻ ngoài của nó, mặc dù không phải không có sắc thái. Ví dụ: mọi đối tượng Thực thể mà bạn đã tạo rõ ràng bằng mã Java và không tải từ cơ sở dữ liệu bằng Hibernate, đều có trạng thái Tạm thời (trong suốt).

EmployeeEntity employee = new EmployeeEntity();

Trạng thái Tạm thời có nghĩa là Hibernate không biết gì về đối tượng này và không có hành động nào trên đối tượng ảnh hưởng đến Hibernate, cũng như Hibernate không hoạt động trên đối tượng này.

Các đối tượng như vậy còn được gọi là POJO - Đối tượng Java cũ đơn giản . Thuật ngữ này thường được sử dụng như một sự tương phản với các đối tượng khác nhau có hành vi gian xảo. Bạn có nhớ các đối tượng Moc mà Mockito đã tạo không? Ở đây họ không phải là POJO.

Nếu một số mã máy khách hoạt động với một đối tượng có trạng thái Tạm thời, thì tương tác của chúng có thể được mô tả bằng sơ đồ siêu đơn giản:

Liên tục hoặc được quản lý

Trường hợp phổ biến tiếp theo là các đối tượng liên quan đến công cụ Hibernate. Trạng thái của chúng được gọi là Liên tục (hoặc Được quản lý). Có chính xác hai cách để có được một đối tượng với trạng thái này:

  • Tải đối tượng từ Hibernate.
  • Lưu đối tượng trong Hibernate.

Ví dụ:

Employee employee = session.load(Employee.class, 1);
Employee employee = new Employee ();
session.save(employee);

Một đối tượng như vậy thường tương ứng với một số loại bản ghi trong cơ sở dữ liệu, nó có ID và những thứ tương tự. Đối tượng này được gắn vào phiên Hibernate và nói chung có thể được biểu diễn không phải bởi một đối tượng thực mà bởi một số loại proxy.

Rất có thể sau khi gọi phương thức session.load() , bạn sẽ lấy lại một số đối tượng sơ khai (proxy) và tất cả các lệnh gọi đến cơ sở dữ liệu sẽ chỉ được thực hiện sau khi gọi các phương thức của đối tượng này. Nhưng chúng ta sẽ nói về những chi tiết như vậy sau.

Và sự tương tác giữa mã máy khách và đối tượng ở trạng thái Được quản lý có thể được mô tả bằng hình ảnh sau:

tách ra

Trạng thái tiếp theo là khi đối tượng đã được tách ra khỏi phiên. Nghĩa là, một khi đối tượng được gắn vào phiên Hibernate, nhưng sau đó phiên bị đóng hoặc giao dịch kết thúc và Hibernate không còn giám sát đối tượng này nữa.

Ví dụ:

session.close();
session.evict(entity);

Trong ví dụ đầu tiên, phiên đã bị đóng. Trong trường hợp thứ hai, chúng tôi đã chỉ ra rõ ràng rằng chúng tôi muốn tách đối tượng khỏi phiên bằng cách sử dụng phương thức evict() .

Sơ đồ tương tác mã-đối ​​tượng mới sẽ giống như sau:

Và đây là nơi nó trở nên thú vị. Nếu đối tượng của bạn được lấy từ Hibernate, thì có khả năng bạn đã được cấp một proxy thay vì một đối tượng thực. Và đối tượng proxy này, sau khi ngắt kết nối khỏi phiên, sẽ đưa ra các ngoại lệ khi các phương thức của nó được gọi.

Đây là vấn đề phổ biến nhất đối với tất cả những người mới bắt đầu khi làm việc với Hibernate. Bạn cần biết chính xác câu trả lời cho những câu hỏi như thế này tại bất kỳ thời điểm nào khi bạn đang làm việc với một đối tượng Thực thể :

  • Bạn có đối tượng thực hay chỉ là proxy từ đối tượng thực?
  • Bạn hiện đang trong một giao dịch hay không?
  • Đây là giao dịch đọc-ghi hay giao dịch chỉ đọc?
  • Đối tượng có được quản lý bởi cơ chế LazyLoading không?
  • Phần nào của đối tượng đã được tải vào bộ nhớ và phần nào sẽ được tải khi được truy cập?
  • Đối tượng của bạn được kết nối với các đối tượng phụ thuộc như thế nào?

Tin tốt là hầu hết thời gian điều đó là hiển nhiên. Nhưng bạn vẫn cần hiểu làm thế nào tất cả hoạt động dưới mui xe. Lập trình khai báo là như vậy - bạn có thể viết mã trong 10 phút, hiểu tại sao nó không hoạt động như bình thường - trong 10 giờ :)

LOẠI BỎ

Và trạng thái cuối cùng mà đối tượng Thực thể của bạn có thể có là Đã xóa. Như bạn có thể đã đoán từ tên của nó, đây là trạng thái của một đối tượng từ xa.

Trạng thái này xuất hiện do thực tế là nếu bạn xóa một số đối tượng khỏi cơ sở dữ liệu, thì đối tượng Java sẽ không biến mất ngay lập tức ở bất kỳ đâu.

Employee employee = session.load(Employee.class, 1);
//after loading the object's state is Persisted

session.remove(employee);
//after deletion, the state of the object is Removed

session.save(employee);
//and now Persisted again

session.close();
//and now the Detached state