我有一个正在使用的旧表,它看起来像这样:
+------------------+--------------+------+-----+---------+-------+
| 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 | |
+------------------+--------------+------+-----+---------+-------+
主要问题是 BinaryData
Java 类加载了 BINARY_DATA
列,即使我只需要 BINARY_DATA_NAME
。我知道构建此架构的最佳方法是将数据与元数据(如文件名)分开,以便它们位于单独的表中。从那里让数据延迟加载变得微不足道。本来就应该这样做。
不幸的是,由于组织限制,我可能无法执行上述操作。作为一种解决方法,是否可以使用一些注释使该列延迟加载而不是将内容拆分到单独的表中?我修改了 BinaryData
类,使它有一个内部静态 BinaryDataData
类,它是 @Embedded
并且属性是 @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... */
不幸的是,这不起作用。即使未请求二进制数据,我看到的 SQL 仍然显示完整的对象提取:
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=?
有什么想法吗?谢谢。
最佳答案
来自 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.
关于java - 使用 Hibernate 延迟获取单列(类属性),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11526255/