懒惰使用Hibernate获取单列(类属性) [英] Lazy fetching single column (class attribute) with Hibernate

查看:78
本文介绍了懒惰使用Hibernate获取单列(类属性)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  + ----- 

我有一张我正在使用的旧表格,它看起来像这样: ------------- + -------------- + ------ + ----- + -------- - + ------- +
|字段|类型|空| Key |默认|额外|
+ ------------------ + -------------- + ------ + ---- - + --------- + ------- +
| BINARY_DATA_ID | varchar(255)| NO | PRI | | |
| BINARY_DATA | longblob |是| | NULL | |
| BINARY_DATA_NAME | varchar(255)|是| | NULL | |
+ ------------------ + -------------- + ------ + ---- - + --------- + ------- +

主要的问题在于 BinaryData Java类加载了 BINARY_DATA 列,即使我只需要 BINARY_DATA_NAME 。我知道构建这个最好的方法是将数据从元数据中分离出来(比如文件名),以便它们存在于不同的表中。从那里数据延迟加载是微不足道的。这是本该如何完成的。



不幸的是,由于组织的限制,我可能无法做到以上几点。作为一种解决方法,是否可以使用一些注释来使该列延迟加载,而不是将事件拆分为单独的表?我修改了 BinaryData 类,以便它有一个内部静态 BinaryDataData 类,它是 @Embedded 和属性是 @Basic(fetch = FetchType.LAZY)



<$
@Table
@Proxy(lazy = false)
@Inheritance(strategy = InheritanceType.JOINED)
public class BinaryData implements Serializable,Persistable< BinaryData> ;, Cloneable {

private static final long serialVersionUID = / ** blah * /;

@Id @Column @GeneratedValue(generator =uuid)@GenericGenerator(name =uuid,strategy =uuid)
private String id;

@Column
private String binaryDataName;

@Embedded
@Basic(fetch = FetchType.LAZY)
private BinaryDataData binaryData;

@Transient
private String cacheId;
$ b $ / **
* Hibernate构造函数
* /
public BinaryData(){/ *创建一个新的Attachment实例。 * /}

public BinaryData(byte [] binaryData,String binaryDataName){
this.binaryData = new BinaryDataData(ArrayUtils.clone(binaryData));
this.binaryDataName = binaryDataName;
}

/ **
*返回BinaryData字节流。
*
* @return binaryData字节流
* /
@Embedded
@Basic(fetch = FetchType.LAZY)
public byte [] getBinaryData( ){
if(this.binaryData == null){
return new byte [0];
}
return binaryData.getActualData();

$ b @Embeddable
public static class BinaryDataData implements Serializable {
@Column(length = 32 * 1024 * 1024,columnDefinition =longblob,name = BINARY_DATA)@Lob
private byte [] actualData;

public BinaryDataData(){}
$ b $ public BinaryDataData(byte [] data){
this.actualData = data;

$ b $ public byte [] getActualData(){
if(this.actualData == null){
return new byte [0];
}
返回this.actualData;
}

public void setBinaryData(byte [] newData){
this.actualData = newData;


@Override public boolean equals(Object obj){
if(this == obj){
return true;
}
if(obj == null){
return false;
}
if(!(obj instanceof BinaryDataData)){
return false;
}
final BinaryDataData other =(BinaryDataData)obj;
if(!Arrays.equals(actualData,other.actualData)){
return false;
}
返回true;
}
}

/ **向前... * /

不幸的是,这不起作用。即使未请求二进制数据,我所看到的SQL仍会显示对象的完整提取:

  select ideaattach0_.BINARY_DATA_ID如BINARY1_9_,ideaattach0_1_.BINARY_DATA如BINARY2_9_,ideaattach0_1_.BINARY_DATA_NAME如BINARY3_9_,ideaattach0_.IDEA_BUCKET_ID如IDEA2_136_从IDEA_ATTACHMENT ideaattach0_内部联接上ideaattach0_.BINARY_DATA_ID = ideaattach0_1_.BINARY_DATA_ID其中ideaattach0_.BINARY_DATA_ID = BINARY_DATA ideaattach0_1_? 

有什么想法?谢谢。

解决方案

From Hibernate,第19章。改进性能


惰性属性读取:访问实例变量时获取属性或单值关联。 这种方法需要构建时间字节码工具,而且很少需要。



I have an old table that I'm working with, which looks like this:

+------------------+--------------+------+-----+---------+-------+
| Field            | Type         | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+-------+
| BINARY_DATA_ID   | varchar(255) | NO   | PRI |         |       |
| BINARY_DATA      | longblob     | YES  |     | NULL    |       |
| BINARY_DATA_NAME | varchar(255) | YES  |     | NULL    |       |
+------------------+--------------+------+-----+---------+-------+

The main problem with this is that the BinaryData Java class loads the BINARY_DATA column, even if I only require the BINARY_DATA_NAME. I know that the best way to architect this is to split the data from the meta-data (like the file name) so they live in separate tables. From there it's trivial to make the data lazy-loaded. This is how it should have been done in the first place.

Unfortunately it may not be possible for me to do the above due to organizational constraints. As a workaround, is it possible to make that column lazy-loaded using some annotations instead of splitting things out into separate tables? I've modified the BinaryData class so that it has an inner static BinaryDataData class which is @Embedded and the attribute is @Basic(fetch=FetchType.LAZY):

@Entity
@Table
@Proxy(lazy=false)
@Inheritance(strategy=InheritanceType.JOINED)
public class BinaryData implements Serializable, Persistable<BinaryData>, Cloneable {

    private static final long serialVersionUID = /** blah */;

    @Id @Column @GeneratedValue(generator="uuid") @GenericGenerator(name="uuid", strategy="uuid")
    private String id;

    @Column
    private String binaryDataName;

    @Embedded
    @Basic(fetch = FetchType.LAZY)
    private BinaryDataData binaryData;

    @Transient
    private String cacheId;

    /**
     * Hibernate constructor
     */
    public BinaryData() { /* Creates a new instance of Attachment. */}

    public BinaryData(byte[] binaryData, String binaryDataName) {
        this.binaryData = new BinaryDataData(ArrayUtils.clone(binaryData));
        this.binaryDataName = binaryDataName;
    }

    /**
     * Returns the BinaryData byte stream.
     *
     * @return binaryData byte stream
     */
    @Embedded
    @Basic(fetch = FetchType.LAZY)
    public byte[] getBinaryData() {
        if (this.binaryData == null) {
            return new byte[0];
        }
        return binaryData.getActualData();
    }

    @Embeddable
    public static class BinaryDataData implements Serializable {
        @Column(length=32*1024*1024, columnDefinition="longblob", name="BINARY_DATA") @Lob
        private byte[] actualData;

        public BinaryDataData() { }

        public BinaryDataData(byte[] data) {
            this.actualData = data;
        }

        public byte[] getActualData() {
            if (this.actualData == null) {
                return new byte[0];
            }
            return this.actualData;
        }

        public void setBinaryData(byte[] newData) {
            this.actualData = newData;
        }

        @Override public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (!(obj instanceof BinaryDataData)) {
                return false;
            }
            final BinaryDataData other = (BinaryDataData) obj;
            if (!Arrays.equals(actualData, other.actualData)) {
                return false;
            }
            return true;
        }
    }

    /** onwards... */

Unfortunately this doesn't work. The SQL that I'm seeing still shows a complete fetch of the object even if the binary data isn't requested:

select ideaattach0_.BINARY_DATA_ID as BINARY1_9_, ideaattach0_1_.BINARY_DATA as BINARY2_9_, ideaattach0_1_.BINARY_DATA_NAME as BINARY3_9_, ideaattach0_.IDEA_BUCKET_ID as IDEA2_136_ from IDEA_ATTACHMENT ideaattach0_ inner join BINARY_DATA ideaattach0_1_ on ideaattach0_.BINARY_DATA_ID=ideaattach0_1_.BINARY_DATA_ID where ideaattach0_.BINARY_DATA_ID=?

Any ideas? Thank you.

解决方案

From Hibernate, Chapter 19. Improving performance:

Lazy attribute fetching: an attribute or single valued association is fetched when the instance variable is accessed. This approach requires buildtime bytecode instrumentation and is rarely necessary.

这篇关于懒惰使用Hibernate获取单列(类属性)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆