2010-01-21 99 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>