2010-01-21 25 views
13

Tôi sử dụng JPA (Hibernate) với Spring. Khi tôi muốn tải lười biếng một tài sản Stirng tôi sử dụng cú pháp sau:@Basic (fetch = FetchType.LAZY) không hoạt động?

@Lob 
@Basic(fetch = FetchType.LAZY) 
public String getHtmlSummary() { 
    return htmlSummary; 
} 

Nhưng khi tôi nhìn vào sql rằng Hibernate tạo ra, có vẻ như bất động sản này không phải là lười biếng nạp? Tôi cũng sử dụng lớp org.hibernate.tool.instrument.javassist.InstrumentTask này trong kịch bản ANT để thiết lập thuộc tính này nhưng có vẻ như nó không hoạt động.

Hãy giúp tôi.

Khosro.

Trả lời

-3

Tìm nạp lười chỉ áp dụng cho các tham chiếu đến các thực thể hoặc tập hợp các thực thể khác. Nó không áp dụng cho các giá trị như String hoặc int.

+0

Không đúng sự thật, LOB có thể được tải chậm. Xem Phần 2.2.2.1 của tài liệu chú thích hibernate-chú thích: http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html#d0e342 - đặc biệt là thuộc tính'CommentComment 'trên ví dụ đó và ghi chú bên dưới. – Cowan

1

từ đặc tả của JPA, họ nói rằng ngay cả khi bạn sử dụng chú thích một thuộc tính được tải xuống một cách lười biếng, điều này không được đảm bảo để được áp dụng, vì vậy các thuộc tính có thể hoặc không tải được (tùy thuộc vào người triển khai JPA) Tuy nhiên, nếu bạn chỉ định rằng bạn nên tìm nạp chúng một cách mong đợi thì trình triển khai JPA phải tải chúng một cách háo hức.

Dòng dưới cùng: @Basic (fetch = FetchType.LAZY) có thể có hoặc không hoạt động, phụ thuộc vào trình cài đặt JPA.

+0

Tôi sử dụng Hibernate và tôi mô tả sự cố ở đây http://stackoverflow.com/questions/2112508/basicfetch-fetchtype-lazy-does-not-work/2112846#2112846 trong câu trả lời của Henning – Khosro

4

Lazy Lob tải sẽ yêu cầu thiết bị bytecode hoạt động bình thường, vì vậy nó không có sẵn theo mặc định trong bất kỳ triển khai JPA nào mà tôi biết.

Đặt cược tốt nhất của bạn là đặt Lob thành một thực thể riêng biệt, như HtmlSummary và sử dụng liên kết một-một-một-được-nạp một cách lười biếng.

+0

Bạn vui lòng cho tôi biết cách thực hiện Tôi sử dụng Hibernate thực hiện của JPA.I cũng làm hướng dẫn mô tả ở đây, nhưng, nó không hoạt động: http: //docs.jboss.org/hibernate/stable/core/reference/en/html_single/#performance-fetching-lazyproperties – Khosro

+0

@ Khosro: Đầu ra của bản ghi Ant nói gì? "Không hoạt động" không đủ thông tin để chẩn đoán vấn đề của bạn, tôi sợ. – Henning

+0

Vâng, tác vụ Ant của tôi hoạt động tốt và đầu ra là [công cụ] chấp nhận chuyển đổi truy cập trường [N ews.textBody] nhưng sau khi chạy ứng dụng, tôi nhận ngoại lệ này org.hibernate.MappingException: Không thể xác định loại cho: org.hibernate.repackage.cglib.transform.impl.InterceptFieldCallback, tại bảng: News, cho các cột: [org.hibernate.mapping.Column (interceptFieldCallback)] trong trường hợp này tôi sử dụng org.hibernate.tool.instrument.cglib. InstrumentTask cho dụng cụ. Trong trường hợp khác khi tôi sử dụng org.hibernate.tool.instrument.javassist.InstrumentTask, ứng dụng triển khai nhưng tải chậm không hoạt động – Khosro

3

Sử dụng FieldHandled với @Basic(fetch=FetchType.LAZY) công trình:

public class myFile implements Serializable, FieldHandled 
{ 

    private FieldHandler  fieldHandler; 

    @Lob 
    @Basic(fetch = FetchType.LAZY) 
    @Column(name = "CONTENT") 
    protected byte[]   content; 
+0

Có ai đã thử điều này không? Nó dường như không hiệu quả với tôi. –

3
@Entity 
public class User implements FieldHandled { 

    @Id 
    private String uid; 

    private String uname; 

    private int age; 

    @Lob 
    @Basic(fetch = FetchType.LAZY) 
    private byte[] img; 

    private FieldHandler fieldHandler; 

    public User() { 
    } 

    // getter() and setter() of uid, uname, age 

    public byte[] getImg() { 
     // if User user = new User() then fieldHandler is null 
     // if User user = entityManager.find(User.class, "001") then fieldHandler is not null 
     if(img != null) { 
      return img; 
     } 

     if (fieldHandler != null) { 
      return (byte[]) fieldHandler.readObject(this, "img", img); 
     } else { 
      return null; 
     } 
    } 

    public void setImg(byte[] img) { 
     this.img = img; 
    } 

    public void setFieldHandler(FieldHandler fieldHandler) { 
     this.fieldHandler = fieldHandler; 
    } 

    public FieldHandler getFieldHandler() { 
     return fieldHandler; 
    } 
} 

tôi sử dụng Hibernate4 h2database.I chắc chắn tải lười biếng có thể hoạt động tốt bởi mã của tôi.

Hibernate: select user0_.uid as uid1_0_0_, user0_.age as age2_0_0_, user0_.uname as uname4_0_0_ from User user0_ where user0_.uid=?

Hibernate: select user_.img as img3_0_ from User user_ where user_.uid=?

nếu sử dụng repository.save(User) để thêm một tài khoản mới sẽ được ok, nhưng cập nhật một tài khoản sẽ ném một ngoại lệ

java.lang.ClassCastException: org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer$1 cannot be cast to java.sql.Blob

tôi đề nghị sử dụng repository.delete(userid) trước repository.save trong một giao dịch, khi đó giao dịch sẽ hoạt động tốt.

3

Trước hết, bạn nên biết rằng thông số kỹ thuật JPA chỉ rõ rằng LAZY chỉ là gợi ý cho các nhà cung cấp JPA, vì vậy nó không phải là một yêu cầu bắt buộc.

Đối với loại hình cơ bản quyến rũ lười biếng để làm việc, bạn cần phải enable bytecode enhancement và thiết lập một cách rõ ràng tài sản enableLazyInitialization cấu hình để true:

<plugin> 
    <groupId>org.hibernate.orm.tooling</groupId> 
    <artifactId>hibernate-enhance-maven-plugin</artifactId> 
    <version>${hibernate.version}</version> 
    <executions> 
     <execution> 
      <configuration> 
       <enableLazyInitialization>true</enableLazyInitialization> 
      </configuration> 
      <goals> 
       <goal>enhance</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 
0

Tôi nghĩ rằng nó sẽ là tương tự như EclipseLink, có bạn cần phải có kích hoạt dệt nếu không, cài đặt tìm nạp sẽ không có hiệu lực. Việc dệt yêu cầu quyền truy cập bytecode. Điều này có thể giúp: https://stackoverflow.com/a/18423704/7159396

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