欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

hibernate普通字段延迟加载无效的解决办法

程序员文章站 2022-06-01 11:47:16
...

关联对象的延迟加载就不说了,大家都知道。 关于普通字段的延迟加载,尤其是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