2010-01-21 98 views
13

我使用JPA(Hibernate)和Spring。 當我想偷懶負載Stirng屬性我使用此語法:@Basic(fetch = FetchType.LAZY)不起作用?

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

但是當我看到,Hibernate對創建SQL,看來這個屬性是不是延遲加載?我也在ANT腳本中使用這個類org.hibernate.tool.instrument.javassist.InstrumentTask來測試這個屬性,但它似乎不起作用。

請幫幫我。

Khosro。

回答

-3

延遲提取僅適用於對其他實體或實體集合的引用。它不適用於像String或int這樣的值。

+0

不正確,LOB可以延遲加載。請參閱hibernate-annotations文檔的第2.2.2.1節:http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html#d0e342 - 特別是該示例的'detailedComment'屬性,以及它下面的註釋。 – Cowan 2010-01-22 02:30:07

1

來自JPA的規範他們說,即使你使用註解一個屬性被延遲取出,這也不能保證被應用,所以屬性可能會或可能不會被懶惰地加載(取決於JPA的實現者)但是,如果您指定應該快速獲取它們,那麼JPA實施者必須加載它們。

底線:@Basic(fetch = FetchType.LAZY)可能工作也可能不工作,取決於JPA實現者。

+0

我使用Hibernate,並且我在這裏描述了這個問題http://stackoverflow.com/questions/2112508/basicfetch-fetchtype-lazy-does-not-work/2112846#2112846在Henning的答案 – Khosro 2010-01-21 22:10:44

4

懶惰Lob加載會要求字節碼檢測工作正常,所以它在默認情況下在我意識到的任何JPA實現中都不可用。

最好的辦法是將Lob放入一個單獨的實體,如HtmlSummary,並使用延遲加載的一對一關聯。

+0

請問您如何使用Hibernate ?我使用JPA的Hibernate實現。我也在這裏做指令描述,但它不起作用:http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#performance-fetching-lazyproperties – Khosro 2010-01-21 21:29:53

+0

@Khosro:Ant日誌輸出是什麼意思?恐怕,「不起作用」的信息還不足以診斷您的問題。 – Henning 2010-01-21 21:38:53

+0

那麼,我的Ant任務運行良好,輸出爲 [儀器]接受字段訪問轉換[N ews.textBody] 但運行應用程序後,我得到了這個異常org.hibernate.MappingException:無法確定類型爲: org.hibernate.repackage.cglib.transform.impl.InterceptFieldCallback,在表中:新聞,爲列:[org.hibernate.mapping.Column(interceptFieldCallback)] 在這種情況下,我使用org.hibernate.tool.instrument.cglib。 InstrumentTask用於檢測。 在另一種情況下,當我使用org.hibernate.tool.instrument.javassist.InstrumentTask,應用程序部署,但延遲加載不起作用 – Khosro 2010-01-21 22:02:19

3

使用FieldHandled與@Basic(fetch=FetchType.LAZY)作品:

public class myFile implements Serializable, FieldHandled 
{ 

    private FieldHandler  fieldHandler; 

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

中默認可用有沒有人試過?它似乎不適合我。 – 2013-08-15 18:55:44

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; 
    } 
} 

我用Hibernate4 h2database.I相信懶加載可以通過我的代碼工作正常。

休眠: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=?

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

如果使用repository.save(User)添加新的用戶將被確定,但更新用戶將拋出一個異常

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

我建議使用repository.delete(userid)之前repository.save在一個事務中,那麼它會正常工作。

3

首先,您應該知道JPA規範明確指出LAZY只是JPA提供程序的一個提示,所以它不是強制性要求。

對於基本型延遲抓取工作,你需要enable bytecode enhancement和明確的enableLazyInitialization配置屬性設置爲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>