2011-06-25 33 views
5

Tôi có kịch bản sau đây (trong Java/Hibernate):Làm cách nào để tránh chèn không cần thiết?

  • Tôi có hai lớp thực thể: X và Y. X có một hiệp hội @ManyToOne Y mà không cascaded.
  • Tôi tạo một thể hiện (không được quản lý) x của X và một thể hiện (không được quản lý) y của Y và điền tham chiếu vào y trong x. Trường duy nhất của y được điền là khóa chính.
  • Thực thể y đã có một hàng tương ứng trong cơ sở dữ liệu cơ sở, nhưng thực thể x là mới.
  • Tôi tồn tại thực thể x.

Khi tôi thực hiện kịch bản này, tôi hy vọng sẽ thấy một truy vấn: INSERT x. Tuy nhiên, những gì thực sự xảy ra là Hibernate thực hiện HAI truy vấn:

  • CHỌN y
  • INSERT x

Hơn nữa, tôi cũng nhận thấy rằng sau khi kiên trì của x, tài liệu tham khảo để y không thực sự trở nên được quản lý và không có phiên bản nào của Y trong phiên! Vì vậy, tại sao là SELECT trên y thực hiện ở tất cả? Có cách nào để ngăn chặn hành vi này không?

Trả lời

2

Bạn không cần (thực sự bạn không nên) khởi tạo Y theo cách thủ công. Bạn có thể làm một biến thể của này (tùy thuộc vào cấu hình của bạn)

Y y = (Y) session.load(Y.class, pk); 

này không lấy Y từ cơ sở dữ liệu, thay vào đó nó tải một proxy chỉ bao gồm từ các vn mà bạn đề cập.

Sau đó gán y cho x và kiên trì x sẽ hoạt động như bạn mong đợi.

+0

Đẹp, hoạt động như một sự quyến rũ! Bất kỳ ý tưởng nào về phần khác của câu hỏi của tôi: trong kịch bản của tôi, tại sao Hibernate thực hiện SELECT trên y? – Rubrick

+0

Tôi đã nghĩ về nó nhưng không có câu trả lời nhất định. Đoán của tôi là vì bạn tạo cá thể thủ công, nó là một đối tượng tách rời (không phải là một đối tượng được quản lý bởi bối cảnh bền vững ngủ đông), vì vậy Hibernate cần kiểm tra xem nó có thực sự tồn tại trong cơ sở dữ liệu hay không. Nhưng tôi không chắc chắn về nó, bởi vì ngay cả khi nó không tồn tại, db sẽ ném một lỗi hạn chế nước ngoài và chèn sẽ có thể ngăn chặn. Tóm lại, tôi không biết :) – SelimOber

Các vấn đề liên quan