2011-10-26 26 views

Trả lời

0

Tôi nhớ này là một câu hỏi một thời gian trở lại (khoảng năm 2007): cụ thể là lý do tại sao các mảng byte đang háo hức lấy thậm chí tho họ được tuyên bố là lười biếng. Dường như các anh chàng Hibernate vẫn chưa sửa vấn đề này.

Dưới đây là một số lựa chọn thay thế khả thi:

Fist, hãy thử chú thích lĩnh vực của bạn với @Lob cũng và xem nếu mà làm việc như mong đợi.

Thứ hai, thay thế byte[] với java.sql.Blob, nó có phương pháp thuận tiện cho bạn để thiết lập và nhận được mảng byte thực tế vì vậy nó sẽ không phải là một refactoring lớn, và điều này thực sự cần giải quyết vấn đề tải lười biếng:

http://download.oracle.com/javase/1.4.2/docs/api/java/sql/Blob.html

+0

Cảm ơn Andrei, nhưng những cách tiếp cận đó không hiệu quả với tôi. VẤN ĐỀ LỚN! '@Lob @Basic (fetch = FetchType.LAZY) Blob private byte [] image;' EntityManager không thể tồn tại thuộc tính này ... tồn tại tất cả các trường và 'hình ảnh' vẫn giữ nguyên. Tôi đang sử dụng lớp bê tông 'SerialBlob' – CelinHC

3

Hãy nhớ rằng nhà cung cấp JPA không bắt buộc phải lấy dữ liệu một cách uể oải khi bạn chỉ định nó. Đó là một gợi ý gợi ý và không phải là yêu cầu.

JPA Specification 2,0 11.1.6

Chiến lược háo hức là một yêu cầu về thời gian chạy cung cấp bền vững mà dữ liệu phải được háo hức vời. Chiến lược LAZY là gợi ý gợi ý cho thời gian chạy của nhà cung cấp kiên trì mà dữ liệu sẽ được tìm nạp lazily khi được truy cập lần đầu tiên. Việc triển khai được được phép háo hức tìm nạp dữ liệu mà gợi ý chiến lược LAZY đã được chỉ định. Trong cụ thể, tìm nạp lười biếng chỉ có thể có sẵn cho Ánh xạ cơ bản mà quyền truy cập dựa trên thuộc tính được sử dụng.

+0

Cảm ơn bạn Pedro! Vì vậy, tôi bị mất? – CelinHC

+0

Pedro, tôi thực sự nghĩ rằng đây là một lỗi Hibernate (nó sẽ không phải là người đầu tiên họ làm trên thực hiện JPA của họ). Xem câu hỏi này: http://stackoverflow.com/questions/2605477/spring-hibernate-blob-lazy-loading. Cơ sở anh chàng có cùng một vấn đề như bạn, giải pháp được đề xuất: tạo một ánh xạ một đối tượng giữa bạn thực thể (sans hình ảnh) và thực thể khác chỉ chứa byte [] và làm cho liên kết đó lười biếng –

+0

@AndreiBodnarescu tất nhiên nó có thể là Lỗi Hibernate, tuy nhiên bạn không thể giả định rằng nhà cung cấp JPA sẽ lười biếng tải dữ liệu của bạn. Theo ý kiến ​​của tôi nếu logic của bạn phụ thuộc vào tính năng như vậy, nó cũng nên được ghi nhận là bạn có thể ngạc nhiên khi thay đổi nhà cung cấp JPA. –

1

Để tải xuống kiến ​​thức của tôi chỉ có thể thực hiện được khi bạn có mối quan hệ @OneToMany (trừ khi bạn sử dụng lớp dệt). Điều này ít nhất là làm thế nào EclipseLink giải thích nó http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Basic_Mappings/Lazy_Basics, và nó có ý nghĩa từ một quan điểm ngôn ngữ java. Khi bạn có

@OneToMany (fetch = FetchType.LAZY) 
Collection<Employee> employees; 

Bộ sưu tập là một giao diện để JPA có thể dễ dàng sử dụng thực hiện bộ sưu tập của riêng mình mà tải dữ liệu một cách lười biếng khi bạn bắt đầu lặp lại qua nó. Nếu bạn có một đối tượng với một trường kiểu byte[] giá trị của nó là null hoặc chứa tất cả dữ liệu, đây là cách Java hoạt động. Cách duy nhất để vượt qua điều này là sử dụng lớp dệt và tạo mã byte trông giống như một mảng byte, nhưng không chứa bất kỳ dữ liệu nào cho đến khi bạn truy cập nó.

2

Bí quyết làm thế nào để đạt được điều này được mô tả trong chủ đề này: http://justonjava.blogspot.it/2010/09/lazy-one-to-one-and-one-to-many.html

Tôi đã cheched nó trên Hibernate v.4.3.5 và JPA v.1.5.0, PostgreSQL 9.3. Làm việc như người ở. Ví dụ:

public class Attachment implements FieldHandled{ 
    @Transient 
    private FieldHandler fieldHandler; 
... 
... 
    @Lob 
    @Column(name=CONTENT, nullable=false) 
    @Basic(fetch = FetchType.LAZY, optional = false) 
    private byte[] content; 

... 
... 
    public byte[] getContent() { 
    if(fieldHandler!=null){ 
     return (byte[])fieldHandler.readObject(this, "content", content); 
    } 
    return content; 
    } 

    public void setContent(byte[] content) { 
    if(fieldHandler!=null){ 
     fieldHandler.writeObject(this, "content", this.content, content); 
     return; 
    } 
    this.content = content; 
    } 

} 

Lưu ý: Nếu bạn đang sử dụng cglib, thực hiện net.sf.cglib.transform.impl.InterceptFieldEnabled thay vì FieldHandled, với phương pháp tương tự.

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