关联对象的延迟加载就不说了,大家都知道。 关于普通字段的延迟加载,尤其是lob字段,若没有延迟加载,对性能影响极大。然而简单的使用 @Basic(fetch = FetchType.LAZY) 注解并没有效果。hibernate对此的解释是Lazy property loading requires buildtime byt
关联对象的延迟加载就不说了,大家都知道。
关于普通字段的延迟加载,尤其是lob字段,若没有延迟加载,对性能影响极大。然而简单的使用 @Basic(fetch = FetchType.LAZY) 注解并没有效果。hibernate对此的解释是Lazy property loading requires buildtime bytecode instrumentation. If your persistent classes are not enhanced, Hibernate will ignore lazy property settings and return to immediate fetching.
而bytecode instrumentation的介绍可以参考http://www.correlsense.com/blog/java-bytecode-instrumentation-an-introduction/,本文不多作介绍。
正是因为我们的persistent classes没有使用bytecode instrumentation增强,才导致了普通字段无法延迟加载。
因此要改写一下。以下为一个使用了bytecode instrumentation的持久类:
public class PublicSchemeTaskFile implements java.io.Serializable , FieldHandled { // Fields /** * */ private static final long serialVersionUID = -8297912895820802249L; private Integer id; private PublicTask publicSchemeTask; private Integer fileType; private String fileName; private byte[] content; private FieldHandler fieldHandler;//用于延迟加载表字段,关联对象延迟加载的话无需此技术 @JSON(serialize = false) public FieldHandler getFieldHandler() { return fieldHandler; } public void setFieldHandler(FieldHandler fieldHandler) { this.fieldHandler = fieldHandler; } // Constructors /** default constructor */ public PublicSchemeTaskFile() { } /** minimal constructor */ public PublicSchemeTaskFile(Integer id) { this.id = id; } // Property accessors @Id @Column(name="ID", unique=true, nullable=false, precision=22, scale=0) @GeneratedValue(strategy=GenerationType.SEQUENCE,generator = "PUBLIC_SCHEME_TASK_FILE_SEQ") public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } @JSON(serialize = false) @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="PUBLIC_TASK_ID") public PublicTask getPublicSchemeTask() { return this.publicSchemeTask; } public void setPublicSchemeTask(PublicTask publicSchemeTask) { this.publicSchemeTask = publicSchemeTask; } @Column(name="FILE_TYPE", precision=22, scale=0) public Integer getFileType() { return this.fileType; } public void setFileType(Integer fileType) { this.fileType = fileType; } @Column(name="FILE_NAME", length=50) public String getFileName() { return this.fileName; } public void setFileName(String fileName) { this.fileName = fileName; } @JSON(serialize = false) @Lob @Basic(fetch = FetchType.LAZY) @Column(name="CONTENT") public byte[] getContent() { if (fieldHandler != null) { return (byte[]) fieldHandler.readObject(this, "content", content); } return null; } public void setContent(byte[] content) { this.content = content; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; PublicSchemeTaskFile other = (PublicSchemeTaskFile) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } }
关键在于FieldHandled接口和lob字段的getter