Я недавно представил улучшение байт-кода в своем проекте Hibernate через плагин hibernate-gain-maven-plugin. Мне действительно нужно иметь возможность лениво инициализировать определенные поля для решения проблем производительности с полями @Lob в сущностях, представляющих документы, и ленивая инициализация всей сущности была невозможной.
Однако я обнаружил, что после того, как было добавлено улучшение байт-кода, ни одно из моих других полей Lazy @ManyToOne не может быть получено. Я выполняю запрос с включенной выборкой, но желаемая сущность является нулевой в результирующем возвращении. Я знаю, что поле не является нулевым в базе данных, и если я удаляю hibernate-gain-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, но нет документа, если у меня есть расширение байт-кода, и это дает мне мой офис и мой документ, если у меня нет улучшения байт-кода.
Я в растерянности. Из того, что я могу прочитать в документации , я должен настроить его правильно. Я что-то упускаю, но я действительно не знаю, что это. Вместо этого я попытался использовать 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.