2010-02-09 5 views
11

Trong Hibernate khi bạn lấy một Entity qua một tải, nếu bạn truy cập mà id accessor Entity của nó không khởi tạo proxy:Khi nào truy xuất id của Hibernate proxy khởi tạo proxy?

Property myProp = (Property) session.load(Property.class, myId); 
myProp.getId(); // Doesn't load the proxy 
myProp.getDescription(); // Loads the proxy from the database hit 

Tuy nhiên, tôi không rõ ràng những gì các quy tắc dành cho proxy hiệp hội bốc. Tôi đã được ấn tượng rằng khi bạn lấy một thực thể thông qua một truy vấn HQL hoặc tiêu chí các quy tắc tương tự áp dụng.

Mỗi Property trong mã của tôi có Company. Các Company được khai báo như vậy:

@ManyToOne(fetch = FetchType.LAZY, optional=false) 
@JoinColumn(name = "company_id", nullable=false) 
private Company company; 

Tuy nhiên, trong mã của tôi tôi đang nhận được N + 1 Selects khi iterating qua PropertiesCompany đang được nạp khi tôi gọi Company.getId().

Trong cả hai đối tượng CompanyProperty, trường id là chú thích dài với @Id.

Có một số cân nhắc khác mà tôi đang thiếu để ngăn việc tải thực thể Company không?

+0

Câu trả lời là một khởi đầu tuyệt vời nhưng nhận xét đầu tiên là câu trả lời hay nhất. Hãy chắc chắn để đọc liên kết mà Gennady Shumakher đăng. Ngoài ra, nếu có ai đó tò mò có một lỗi trong cơ sở dữ liệu Hibernate về vấn đề này mà tôi đã tìm thấy: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3718 – jbarz

Trả lời

10

Nó không hoạt động như mong đợi chỉ vì bạn phải sử dụng quyền truy cập thuộc tính thay vì truy cập trường.

Thay vì

@ManyToOne(fetch=FetchType.LAZY, optional=false) 
@JoinColumn(name="COMPANY_ID", nullable=false) 
private Company company; 

Sử dụng

@ManyToOne(fetch=FetchType.LAZY, optional=false) 
@JoinColumn(name="COMPANY_ID", nullable=false) 
public Company getCompany() { 
    return this.company; 
} 

Đưa quan tâm bạn không thể sử dụng truy cập bất động sản và lĩnh vực acces cùng một lúc. Vì vậy, bạn nên chọn một phương pháp.

liên quan,

+2

+1 - giải thích chi tiết hơn có sẵn ở đây: http://www.catalysts.cc/en/blog/ejb-annotations-hibernate-lazy-loading/ –

+0

Tôi thấy, từ đọc bài viết nó có vẻ như cách tiếp cận đúng là thực sự thay đổi đối tượng Công ty để chú thích là tất cả trên getters. Quan trọng hơn là phương thức getId() được chú thích hơn là getCompany() trên thuộc tính. – jbarz

+1

Java Persistence with Hibernate - (www.manning.com/bauer2) đề cập đến điểm này trong "13.1.3 Understanding Proxies": "Miễn là bạn chỉ truy cập thuộc tính định danh cơ sở dữ liệu, không cần khởi tạo proxy. (Lưu ý rằng điều này không đúng nếu bạn ánh xạ thuộc tính định danh với truy cập trực tiếp trường; Hibernate sau đó thậm chí không biết rằng phương thức getId() tồn tại. Nếu bạn gọi nó, proxy phải được khởi tạo.) ' . –