Не удается получить объект LazyToOne в режиме гибернации с улучшениями байт-кода

#java #hibernate #fetch #lazy-loading #byte-code-enhancement

#java #переход в режим гибернации #извлечение #отложенная загрузка #улучшение байт-кода

Вопрос:

Недавно я внедрил улучшение байт-кода в свой проект Hibernate с помощью hibernate-enhance-maven-plugin. Мне действительно нужно иметь возможность лениво инициализировать определенные поля для решения проблем с производительностью с полями @Lob в объектах, которые представляют документы, и ленивая инициализация всего объекта не была вариантом.

Однако я обнаружил, что после внедрения улучшения байт-кода ни одно из моих других полей Lazy @ManyToOne не может быть извлечено. Я выполняю запрос с включенной выборкой, но в результирующем возврате желаемый объект равен null. Я знаю, что поле в базе данных не равно null, и если я удалю hibernate-enhance-maven-plugin и перекомпилирую, выборка будет работать так, как ожидалось.

Ниже приведен основной объект, который я пытаюсь извлечь (Office), и объект lazy ManyToOne, который я пытаюсь извлечь (Document).

     @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 и мой документ, если у меня НЕТ улучшения байт-кода.

Я в растерянности. Из того, что я могу прочитать в документации, я должен правильно настроить его. Мне чего-то не хватает, но я действительно не знаю, чего именно. Вместо этого я попытался использовать 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: 
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.