有很多人可以找到关于这个谷歌搜索,但我还没有找到一个可行的解决方案来解决这个问题。
基本上我所拥有的是一个特定类的大型CLOB,我希望按需加载。这种天真的方式是:
class MyType {
// ...
@Basic(fetch=FetchType.LAZY)
@Lob
public String getBlob() {
return blob;
}
}
虽然这不起作用,显然是因为我正在使用oracle驱动程序,即Lob对象不被视为简单句柄但总是被加载。或者我已经被引导相信我的想法。有一种解决方案使用特殊的工具来进行延迟属性加载,但是由于Hibernate文档似乎表明他们对使这项工作正确无益,所以我宁愿不去那条路。特别是必须运行额外的编译通道和所有。
因此,我设想的下一个解决方案是将此对象分离为另一种类型并定义关联。不幸的是,虽然文档提供了相互矛盾的信息,但很明显,延迟加载对OneToOne与共享主键的关联不起作用。我将关联的一方设置为ManyToOne,但是当我有共享主键时,我不太确定如何执行此操作。
那么有人可以提出最好的解决方法吗?
答案 0 :(得分:5)
根据this,只有PostgreSQL将Blob实现为非常懒惰。所以最好的解决方案是将blob移动到另一个表。你必须使用共享主键吗?你为什么不这样做:
public class MyBlobWrapper {
@Id
public Long getId() {
return id;
}
@Lob
public String getBlob() {
return blob;
}
@OneToOne(fetch=FetchType.LAZY,optional=false)
public MyClass getParent() {
return parent;
}
}
答案 1 :(得分:5)
可以尝试将字段从String
转换为Clob
(或Blob
),而不是使用hibernate注释进行equilibristics:
@Lob
@Basic(fetch=FetchType.LAZY)
@Column(name = "FIELD_COLUMN")
public Clob getFieldClob() {
return fieldClob;
}
public void setFieldClob(Clob fieldClob) {
this.fieldClob = fieldClob;
}
@Transient
public String getField()
{
if (this.getFieldClob()==null){
return null;
}
try {
return MyOwnUtils.readStream(this.getFieldClob().getCharacterStream());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void setField(String field)
{
this.fieldClob = Hibernate.createClob(field);
}
为我工作(该领域开始懒散地加载到Oracle上)。
答案 2 :(得分:3)
由于您似乎正在使用Hibernate,我想知道您的问题是否与以下Hibernate功能有关:
Using Lazy Properties Fetching
Hibernate3支持延迟获取各个属性。这个 优化技术也称为获取组。请注意 这主要是营销功能;优化行读取更多 比列读数的优化更重要。但是,只能加载 在极端情况下,类的某些属性可能很有用。对于 例如,遗留表有数百列和数据 模型无法改进。
延迟属性加载需要构建时字节码检测。如果 你的持久化类没有增强,Hibernate会忽略懒惰 属性设置并返回立即获取。
答案 3 :(得分:1)
老帖子,但只有一个帮助了我,感谢@TadeuszKopec回答。
看起来很难用JPA延迟加载blob。我尝试过@OneToOne协会,但它的复杂性不仅仅是帮助。 我只是将字节移动到另一个类,与MyClass没有关联(父。相同的表,相同的id):
em.persist(parent);
em.flush();
em.merge(new MyBlobWrapper(parent_id,new byte[1000]));
请记住在保存blob之前刷新父级:
String query1 = " select PDF from MyBlobWrapper PDF where PDF.id = :id";
现在我可以单独加载pdf:
Thread t = new Thread(() -> {
repository.findById(1); // this line blocks the thread
}
t.start();
t.join();
我只是JPA的初学者,希望有所帮助。