Sự khác biệt giữa Kiên trì () và Hợp nhất () trong JPA và Hibernate là gì?


119

Sự khác biệt giữa Kiên trì () và merge () trong Hibernate là gì?

persist() có thể tạo truy vấn CẬP NHẬT & CHÈN, ví dụ:

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
A a=new A();
session.persist(a);
a.setName("Mario");
session.flush();

trong trường hợp này truy vấn sẽ được tạo như thế này:

Hibernate: insert into A (NAME, ID) values (?, ?)
Hibernate: update A set NAME=? where ID=?

vì vậy persist()phương pháp có thể tạo một Chèn và một Cập nhật.

Bây giờ với merge():

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

Đây là những gì tôi thấy trong cơ sở dữ liệu:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Madonna
3           Elvis Presley
4           Luciano Pavarotti

Bây giờ hãy cập nhật bản ghi bằng merge()

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setId(2);
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

Đây là những gì tôi thấy trong cơ sở dữ liệu:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Luciano Pavarotti
3           Elvis Presley

7
Javadoc rất rõ ràng về những gì họ làm và sự khác biệt là gì. Bạn đã đọc và hiểu nó chưa?
skaffman


Câu trả lời:


144

Đặc tả JPA chứa mô tả rất chính xác về ngữ nghĩa của các hoạt động này, tốt hơn so với trong javadoc:

Ngữ nghĩa của hoạt động liên tục , được áp dụng cho thực thể X như sau:

  • Nếu X là một thực thể mới, nó sẽ được quản lý. Thực thể X sẽ được nhập vào cơ sở dữ liệu tại hoặc trước khi cam kết giao dịch hoặc kết quả của hoạt động tuôn ra.

  • Nếu X là một thực thể được quản lý từ trước, nó sẽ bị bỏ qua bởi hoạt động liên tục. Tuy nhiên, hoạt động duy trì được xếp tầng cho các thực thể được tham chiếu bởi X, nếu các mối quan hệ từ X với các thực thể khác này được chú thích bằng giá trị phần tử cascade=PERSISThoặc cascade=ALLchú thích hoặc được chỉ định bằng phần tử mô tả XML tương đương.

  • Nếu X là một thực thể bị xóa, nó sẽ được quản lý.

  • Nếu X là một đối tượng tách rời, đối tượng EntityExistsExceptioncó thể được ném ra khi thao tác liên tục được gọi, hoặc đối tượng EntityExistsExceptionkhác PersistenceExceptioncó thể được ném vào thời gian xả hoặc cam kết.

  • Đối với tất cả các thực thể Y được tham chiếu bởi một mối quan hệ từ X, nếu mối quan hệ với Y đã được chú thích bằng giá trị phần tử tầng cascade=PERSISThoặc cascade=ALLthì thao tác duy trì được áp dụng cho Y.


Ngữ nghĩa của thao tác hợp nhất được áp dụng cho thực thể X như sau:

  • Nếu X là một thực thể tách rời, trạng thái của X được sao chép vào một cá thể thực thể được quản lý đã tồn tại từ trước X 'có cùng danh tính hoặc một bản sao được quản lý mới X' của X được tạo.

  • Nếu X là một cá thể thực thể mới, một cá thể thực thể được quản lý mới X 'được tạo và trạng thái của X được sao chép vào cá thể thực thể được quản lý mới X'.

  • Nếu X là một cá thể thực thể đã bị loại bỏ, một IllegalArgumentExceptionsẽ được ném ra bởi hoạt động hợp nhất (hoặc cam kết giao dịch sẽ không thành công).

  • Nếu X là một thực thể được quản lý thì thao tác này sẽ bị bỏ qua bởi thao tác hợp nhất, tuy nhiên, thao tác hợp nhất được xếp tầng cho các thực thể được tham chiếu bởi các mối quan hệ từ X nếu các mối quan hệ này đã được chú thích bằng giá trị phần tử phân tầng cascade=MERGEhoặc cascade=ALLchú thích.

  • Đối với tất cả các thực thể Y được tham chiếu bởi các mối quan hệ từ X có giá trị phần tử tầng cascade=MERGEhoặccascade=ALL , Y được hợp nhất một cách đệ quy thành Y '. Đối với tất cả Y như vậy được tham chiếu bởi X, X 'được đặt thành tham chiếu Y'. (Lưu ý rằng nếu X được quản lý thì X là cùng một đối tượng với X '.)

  • Nếu X là một thực thể được hợp nhất thành X ', với một tham chiếu đến một thực thể Y khác, trong đó cascade=MERGEhoặc cascade=ALLkhông được chỉ định, thì việc điều hướng của cùng một liên kết từ X' mang lại một tham chiếu đến một đối tượng được quản lý Y 'có cùng danh tính liên tục như Y.


Cảm ơn bạn về thông tin. Tôi thấy ngữ nghĩa của cả hai định nghĩa. Nhưng câu hỏi là về sự khác biệt giữa chúng. Có lẽ nên trình bày danh sách các trạng thái và 2 tiểu mục cho từng hành vi khác nhau của persistvs merge?
AlikElzin-kilaka

25

Điều này đến từ JPA. Theo một cách rất đơn giản:

  • persist(entity) nên được sử dụng với các thực thể hoàn toàn mới, để thêm chúng vào DB (nếu thực thể đã tồn tại trong DB thì sẽ có EntityExistsException ném).

  • merge(entity) nên được sử dụng, để đưa thực thể trở lại bối cảnh tồn tại nếu thực thể đã bị tách ra và đã bị thay đổi.


bạn có thể vui lòng thêm một nguồn để giải thích của bạn? Cảm ơn.
AlikElzin-kilaka

@ AlikElzin-kilaka giải thích như vậy, theo tôi nhớ, tôi đã tìm thấy trong một cuốn sách "Bắt đầu Java EE 7".
Krystian

12

Persist chỉ nên được gọi trên các thực thể mới, trong khi hợp nhất có nghĩa là gắn lại các thực thể đã tách rời.

Nếu bạn đang sử dụng trình tạo được chỉ định, việc sử dụng hợp nhất thay vì duy trì có thể gây ra câu lệnh SQL dư thừa , do đó ảnh hưởng đến hiệu suất.

Ngoài ra, việc gọi hợp nhất cho các thực thể được quản lý cũng là một sai lầm vì các thực thể được quản lý được quản lý tự động bởi Hibernate và trạng thái của chúng được đồng bộ hóa với bản ghi cơ sở dữ liệu bằng cơ chế kiểm tra bẩn khi xóa bối cảnh Persistence .


1

Sự khác biệt quan trọng nhất là:

  • Trong trường hợp của persistphương thức, nếu đối tượng sẽ được quản lý trong ngữ cảnh tồn tại, đã tồn tại trong ngữ cảnh tồn tại, thì đối tượng mới sẽ bị bỏ qua. (Không có chuyện gì xảy ra)

  • Nhưng trong trường hợp mergemethod, thực thể đã được quản lý trong ngữ cảnh lâu dài sẽ được thay thế bằng thực thể mới (cập nhật) và bản sao của thực thể được cập nhật này sẽ quay trở lại. (từ bây giờ mọi thay đổi sẽ được thực hiện trên thực thể được trả lại này nếu bạn muốn phản ánh những thay đổi của mình trong ngữ cảnh tồn tại)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.