我最近通过hibernate-enhance-maven-plugin将字节码增强功能引入了我的Hibernate项目。我真的需要能够延迟初始化某些字段,以解决代表文档的实体中@Lob字段的性能问题,并且延迟初始化整个实体不是一种选择。
但是,我发现在引入字节码增强之后,无法获取我的其他Lazy @ManyToOne字段。我执行了包含提取的查询,但是所需的实体在返回的结果中为null。我知道数据库中的字段不是null,如果我删除了hibernate-enhance-maven-plugin并重新编译,提取操作将按预期进行。
下面是我要检索的主要实体(Office)和我要获取的懒惰的ManyToOne实体(文档)。
@Entity
@DynamicInsert
@DynamicUpdate
@SelectBeforeUpdate
@Table(name="OFFICES")
@Audited
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "myCache")
public class Office implements Serializable {
....
private Document businessPlan;
@ManyToOne(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
@JoinColumn(name = "FK_DOCUMENT")
@LazyToOne(LazyToOneOption.NO_PROXY)
public Document getBusinessPlan() {
return businessPlan;
}
public void setBusinessPlan(Document businessPlan) {
this.businessPlan= businessPlan;
}
....
}
我设置了条件,并尝试使用JPQL从数据库中提取数据。
String hql = "select _it from com.mycom.model.Office _it left join fetch _it.businessPlan as a1_businessPlan where _it.id = :p1";
Query query = session.createQuery(hql).setParameter("p1", officeId);
return query.setCacheable(true).list();
如果我具有字节码增强功能,这将给我我的Office但没有文档,如果我没有字节码增强功能,这将给我Office和我的文档。
我很茫然。根据我的read in the documentation,我应该正确地设置它。我错过了一些东西,但我真的不知道它是什么。我尝试使用CriteriaBuilder作为测试,只是为了看看它是否有所作为,但结果是相同的:
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Office> query = builder.createQuery(Office.class);
Root<Office> root = query.from(Office.class);
root.fetch("businessPlan", JoinType.LEFT);
query.select(root).where(
builder.equal(root.get("id"), officeId)
);
Office testOffice = session.createQuery(query).getSingleResult();
System.out.println(testOffice.getBusinessPlan());//is null
更令人困惑的是,生成的SQL似乎是准确的。进行抓取时,Hibernate显示以下内容:
Hibernate:
select
office0_.ID as ID1_94_0_,
...
document1_.ID as ID1_121_1_,
document1_.CONTENTTYPE as CONTENTTYPE2_121_1_,
document1_.DOCUMENTNAME as DOCUMENTNAME3_121_1_,
document1_.PDF as PDF4_121_1_
from
OFFICES office0_ left outer join DOCUMENTS document1_ on office0_.FK_DOCUMENT=document1_.ID
where
office0_.ID=?
直接在我的数据库上运行,可以纯粹地用原始的方式找到我想要的东西
目前,我正在使用Hibernate 5.4.2.Final,如您所见,其中包括Envers。