2015-10-19 16 views
7

Tôi đọc rằng getOne() được tải xuống và findOne() tìm nạp toàn bộ thực thể ngay lập tức. Tôi đã kiểm tra nhật ký gỡ lỗi và thậm chí tôi đã bật giám sát trên máy chủ sql của mình để xem những câu lệnh nào được thực thi, tôi thấy rằng cả hai số getOne()findOne() đều tạo và thực hiện cùng một truy vấn. Tuy nhiên khi tôi sử dụng getOne() các giá trị ban đầu là null (ngoại trừ id của khóa học).Sự khác biệt giữa CrudRepository findOne() và JpaRepository getOne()

Vì vậy, bất cứ ai có thể vui lòng cho tôi biết, nếu cả hai phương pháp thực hiện cùng một truy vấn trên cơ sở dữ liệu, tại sao tôi nên sử dụng một cái khác? Tôi về cơ bản đang tìm kiếm một cách để lấy một thực thể mà không nhận được tất cả các con/thuộc tính của nó.

EDIT1:

Entity code

đang Dao:

@Repository 
public interface FlightDao extends JpaRepository<Flight, Long> { 
} 

Debugging log findOne() vs getOne()

EDIT2:

Nhờ Chlebik tôi đã có thể xác định được vấn đề. Giống như Chlebik đã nêu, nếu bạn cố truy cập bất kỳ thuộc tính nào của thực thể được tìm nạp bởi getOne(), truy vấn đầy đủ sẽ được thực thi. Trong trường hợp của tôi, tôi đã kiểm tra hành vi trong khi gỡ lỗi, di chuyển một dòng tại một thời điểm, tôi hoàn toàn quên rằng trong khi gỡ lỗi IDE cố gắng truy cập các thuộc tính đối tượng cho mục đích gỡ lỗi (hoặc ít nhất đó là những gì tôi nghĩ đang xảy ra). thực hiện truy vấn đầy đủ. Tôi ngừng gỡ lỗi và sau đó kiểm tra nhật ký và mọi thứ có vẻ bình thường.

getOne() vs findOne() (log này được lấy từ MySQL general_log và không ngủ đông.

Debugging log

No debugging log

Trả lời

6

Nó chỉ là một phỏng đoán nhưng trong 'tinh khiết JPA' có một phương pháp EntityManager được gọi là getReference. Và nó được thiết kế để lấy thực thể với chỉ ID trong đó, sử dụng của nó chủ yếu là để chỉ tham chiếu tồn tại mà không cần lấy toàn bộ thực thể. thơ ca ngợi sẽ nói rõ hơn:

// em is EntityManager 
Department dept = em.getReference(Department.class, 30); // Gets only  entity with ID property, rest is null 
Employee emp = new Employee(); 
emp.setId(53); 
emp.setName("Peter"); 
emp.setDepartment(dept); 
dept.getEmployees().add(emp); 
em.persist(emp); 

tôi giả sử sau đó getOne phục vụ cùng một mục đích. Tại sao các truy vấn được tạo giống nhau bạn hỏi? Vâng, AFAIR trong kinh thánh JPA - Pro JPA2 của Mike Keith và Merrick Schincariol - hầu như mọi đoạn đều chứa một cái gì đó như 'hành vi phụ thuộc vào nhà cung cấp'.

EDIT:

Tôi đã thiết lập của riêng mình. Cuối cùng tôi đã kết luận rằng nếu bạn trong bất kỳ cách nào can thiệp vào thực thể lấy với getOne (thậm chí đi cho entity.getId()) nó gây ra SQL được thực hiện. Mặc dù nếu bạn đang sử dụng nó chỉ để tạo proxy (ví dụ như cho chỉ báo quan hệ như được hiển thị trong một mã ở trên), không có gì xảy ra và không có SQL bổ sung nào được thực hiện. Vì vậy, tôi giả định trong lớp dịch vụ của bạn Bạn làm điều gì đó với thực thể này (sử dụng getter, log something) và đó là lý do tại sao đầu ra của hai phương thức này trông giống nhau.

ChlebikGitHub with example code
SO helpful question #1
SO helpful question #2

+0

Cảm ơn thông tin. Trên thực tế những gì 'getOne()' thực hiện gọi là 'getReference() '. Tôi thực sự bối rối vì như tôi đã nói trước đó cả hai phương thức được tạo và thực hiện cùng một truy vấn! Vì vậy, có lẽ nó phải làm với MySQL như bạn đã nói? Tôi thực sự muốn ai đó có thể xác nhận điều này. Bạn có bất kỳ ý tưởng nếu truy vấn nên khác nhau giữa hai phương pháp trong một kịch bản bình thường? – prettyvoid

+0

Nhà cung cấp không có nghĩa là ví dụ. MySQL nhưng Hibernate/TopLink/bất cứ điều gì bạn sử dụng. Tôi cho rằng truy vấn đang được thực hiện dựa trên các quan hệ đã xác định trong các thực thể của bạn và có thể tối ưu hóa được thực hiện bởi việc thực hiện JPA. IMHO với thực thể đơn giản không có nhiều khác biệt giữa việc tìm nạp trình xử lý cho một thực thể (như với ** getReference **) và truy xuất thực tế tất cả dữ liệu. – Chlebik

+0

Tôi phải lấy một tham chiếu vì các thực thể tôi cố gắng tìm nạp có rất nhiều thực thể con, đó là rất nhiều công việc để tìm nạp toàn bộ nội dung khi tôi chỉ cần ID của thực thể. Chúng ta hãy chờ một thời gian có thể ai đó có thể cho chúng tôi biết điều gì đang xảy ra. Cảm ơn bạn lần nữa – prettyvoid

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