[英]@Basic(fetch = FetchType.LAZY) does not work?
我将 JPA (Hibernate) 与 Spring 一起使用。 当我想延迟加载字符串属性时,我使用以下语法:
@Lob
@Basic(fetch = FetchType.LAZY)
public String getHtmlSummary() {
return htmlSummary;
}
Lazy Lob
加载需要字节码检测才能正常工作,因此默认情况下它在我所知道的任何JPA实现中都不可用。
最好的办法是将Lob放入一个单独的实体,如HtmlSummary
,并使用一个懒惰加载的一对一关联。
使用FieldHandled和@Basic @Basic(fetch=FetchType.LAZY)
有效:
public class myFile implements Serializable, FieldHandled
{
private FieldHandler fieldHandler;
@Lob
@Basic(fetch = FetchType.LAZY)
@Column(name = "CONTENT")
protected byte[] content;
@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。我确定延迟加载可以通过我的代码正常工作。
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=?
如果使用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
在一个事务性的,那么它会正常工作。
首先,您应该知道JPA规范明确规定LAZY只是对JPA提供商的暗示,因此它不是强制性要求。
要使基本类型的延迟抓取工作,您需要启用字节码增强并将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>
根据JPA的规范,他们说即使你使用注释属性来懒惰地获取,也不能保证应用,因此属性可能会或可能不会被懒惰地加载(取决于JPA的实现者),但是如果你指定你应该急切地获取它们然后JPA实现者必须急切地加载它们。
底线:@Basic(fetch = FetchType.LAZY)可能有效,也可能无效,取决于JPA实现者。
我认为它类似于EclipseLink,你需要启用编织,否则fetch设置不起作用。 编织需要字节码访问。 这可能会有所帮助: https : //stackoverflow.com/a/18423704/7159396
我用
@Lob<\/code>注释了我的列,它的类型是
byte[]<\/code> ,但它总是急切地加载。
我尝试过了:
用@Basic(fetch = FetchType.LAZY)<\/code>注释它
<\/li>
设置hibernate.bytecode.use_reflection_optimizer=false<\/code>
<\/li><\/ul> 但这些解决方案都没有奏效。
我最终使用
Blob<\/code>而不是
byte[]<\/code>
这个会被延迟加载,如果您需要检索它的值,请访问此字段:
延迟提取仅适用于对其他实体或实体集合的引用。 它不适用于String或int之类的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.