不幸的是,下面的代码不起作用。始终检索图像!
@Entity
public Car implements Serializable {
...
@Basic(fetch = FetchType.LAZY) //Neither with @Lob
private byte[] image;
...
}
SETUP :JPA 2.0 / Hibernate 3.5 / MySQL 5.5
答案 0 :(得分:3)
请记住,JPA提供程序在您指定数据时不需要懒惰地获取数据。这是提示而非要求。
JPA Specification 2.0 11.1.6
EAGER策略是持久性提供程序运行时的一项要求,必须急切地获取数据。 LAZY策略是持久性提供程序运行时的提示,应该懒惰地获取数据 什么时候第一次访问。执行是允许急切地 获取已指定LAZY策略提示的数据。在 特别是,延迟提取可能仅适用于基本映射 使用基于属性的访问。
答案 1 :(得分:2)
如何实现本主题中描述的技巧:http://justonjava.blogspot.it/2010/09/lazy-one-to-one-and-one-to-many.html
我已经在Hibernate v.4.3.5和JPA v.1.5.0,PostgreSQL 9.3上做了它。工作就像一个魅力。 例如:
public class Attachment implements FieldHandled{
@Transient
private FieldHandler fieldHandler;
...
...
@Lob
@Column(name=CONTENT, nullable=false)
@Basic(fetch = FetchType.LAZY, optional = false)
private byte[] content;
...
...
public byte[] getContent() {
if(fieldHandler!=null){
return (byte[])fieldHandler.readObject(this, "content", content);
}
return content;
}
public void setContent(byte[] content) {
if(fieldHandler!=null){
fieldHandler.writeObject(this, "content", this.content, content);
return;
}
this.content = content;
}
}
注意:如果您使用的是CGLib,请使用相同的方法实现net.sf.cglib.transform.impl.InterceptFieldEnabled而不是FieldHandled。
答案 2 :(得分:1)
据我所知,只有当你有@OneToMany关系时才可以进行延迟加载(除非你使用类编织)。至少这是EclipseLink如何解释它http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Basic_Mappings/Lazy_Basics,从java语言的角度来看它是有意义的。 当你有
@OneToMany (fetch = FetchType.LAZY)
Collection<Employee> employees;
Collection是一个接口,因此JPA可以轻松使用自己的Collections实现,当您开始迭代时,它会懒散地加载数据。如果您的对象具有类型为byte[]
的字段,则其值为null或包含所有数据,这就是Java的工作方式。解决这个问题的唯一方法是使用类编织并创建看起来像字节数组的字节代码,但在访问它之前不包含任何数据。
答案 3 :(得分:0)
我记得这是一个问题(大约在2007年):即为什么字节数组被急切地提取,即使它们被宣布为懒惰。显然,Hibernate的人还没有解决这个问题。
以下是一些可行的替代方案:
拳头,尝试使用@Lob
注释您的字段,看看它是否按预期工作。
其次,将byte[]
替换为java.sql.Blob
,它具有设置和获取实际字节数组的便捷方法,因此它不会是一个很大的重构,这实际上应该解决延迟加载问题:
http://download.oracle.com/javase/1.4.2/docs/api/java/sql/Blob.html