Java @Basic(fetch=FetchType.LAZY)不工作?

Java @Basic(fetch=FetchType.LAZY)不工作?,java,hibernate,jpa,orm,lazy-loading,Java,Hibernate,Jpa,Orm,Lazy Loading,我将JPA(Hibernate)与Spring一起使用。 当我想延迟加载Stirng属性时,我使用以下语法: @Lob @Basic(fetch = FetchType.LAZY) public String getHtmlSummary() { return htmlSummary; } 但是当我查看hibernate创建的sql时,这个属性似乎不是延迟加载的?我还在ANT脚本中使用这个类org.hibernate.tool.instrument.javassist.Instrume

我将JPA(Hibernate)与Spring一起使用。 当我想延迟加载Stirng属性时,我使用以下语法:

@Lob
@Basic(fetch = FetchType.LAZY)
public String getHtmlSummary() {
    return htmlSummary;
}
但是当我查看hibernate创建的sql时,这个属性似乎不是延迟加载的?我还在ANT脚本中使用这个类org.hibernate.tool.instrument.javassist.InstrumentTask来检测这个属性,但它似乎不起作用

请帮帮我


Khosro.

延迟抓取仅适用于对其他实体或实体集合的引用。它不适用于字符串或int之类的值。

根据JPA规范,他们说,即使使用注释属性进行延迟获取,也不能保证应用该属性,因此属性可能会延迟加载,也可能不会延迟加载(取决于JPA的实现者),但是,如果您指定应该急切地获取它们,那么JPA实现者必须急切地加载它们


底线:@Basic(fetch=FetchType.LAZY)可能工作,也可能不工作,这取决于JPA实现者。

LAZY
Lob
加载需要字节码插装才能正常工作,因此在我所知道的任何JPA实现中,默认情况下它都不可用


最好将Lob放入一个单独的实体中,如
HtmlSummary
,并使用一个延迟加载的一对一关联

使用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;
我使用Hibernate4 H2数据库。我相信惰性加载可以通过我的代码正常工作

休眠:
从用户user0中选择user0.uid作为uid1\u 0\u 0,user0.age作为age2\u 0\u,user0.uname作为unae4\u 0\u,其中user0.uid=?

休眠:
从user user\uuu其中user.uid=?

如果使用
repository.save(User)
添加一个新用户是可以的,但是更新一个用户会抛出一个异常

java.lang.ClassCastException:org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer$1不能强制转换为java.sql.Blob


我建议在
repository.delete(userid)
之前使用
repository.save
在一个事务中,那么它就可以正常工作。

首先,您应该知道JPA规范明确规定,LAZY只是对JPA提供者的一个提示,所以它不是强制性要求


要使基本类型的延迟抓取工作,您需要将
enablelazyinstalization
configuration属性显式设置为
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>

org.hibernate.orm.tooling
hibernate增强maven插件
${hibernate.version}
真的
增强

我认为它类似于EclipseLink,您需要启用编织,否则,获取设置将无效。 编织需要字节码访问。
这可能会有帮助:

您能告诉我如何插入指令吗?我使用JPA的Hibernate实现。我也在这里描述指令,但它不起作用:@Khosro:Ant日志输出说什么?“不工作”恐怕不足以诊断您的问题。嗯,我的Ant任务工作得很好,输出是[instrument]接受字段访问转换[N ews.textBody]但在运行应用程序后,我得到了以下异常:org.hibernate.MappingException:无法确定org.hibernate.repackage.cglib.transform.impl.InterceptFieldCallback的类型,在表:News中,列:[org.hibernate.mapping.Column(InterceptFieldCallback)]在本例中,我使用org.hibernate.tool.instrument.cglib.InstrumentTask进行检测。在另一种情况下,当我使用org.hibernate.tool.instrument.javassist.InstrumentTask时,应用程序会部署但延迟加载不起作用“不起作用”意味着,当我从数据库获取新闻时,它也会获取textBody,但是根据延迟加载,它不能被提取。@Khosro:org.hibernate.repackage.cglib.transform.impl.InterceptFieldCallback在运行时是否在类路径上?我使用hibernate,我在Henning的回答中描述了这个问题不正确,LOB可以被延迟加载。请参阅hibernate annotations文档的第2.2.2.1节:——特别是该示例上的“detailedComment”属性,以及下面的注释。我包括了这个插件,但仍然不起作用。(在实体的选择中,文件的列也被投影)“基本类型延迟抓取工作…”。这意味着启用它对许多字段都不是必需的?如果是这样的话,如果我将这类字段设置为真会发生什么?谢谢Vlad。我为ManyTone单向设置了惰性抓取,但没有将enableLazyInitialization设置为true,并检查了hibernate日志,也没有将关联与父实体一起抓取,这对我来说意味着一切都很好。如果我不对基本类型使用任何延迟抓取,我应该将enableLazyInitialization设置为true吗?正如这个StackOverflow答案中所述,只有基本类型延迟抓取工作时才需要enableLazyInitialization。如果关联标记为
FetchType.LAZY
,则可以延迟获取关联,而无需任何额外设置。
<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>