Cannot Fetch LazyToOne Entity In Hibernate With Bytecode Enhancements

414 Views Asked by At

I recently introduced Bytecode Enhancement into my Hibernate project via the hibernate-enhance-maven-plugin. I really need to be able to lazily initialize certain fields to address performance issues with @Lob fields in entities that represent documents, and lazily initializing the entire entity wasn't an option.

However, I've found that after Bytecode Enhancement has been introduced, none of my other Lazy @ManyToOne fields can be fetched. I execute the query with the fetch included, but the desired entity is null in the resulting return. I know the field is not null in the database and if I remove the hibernate-enhance-maven-plugin and recompile the fetch works as expected.

Below is the primary entity I'm trying to retrieve (Office) and the lazy ManyToOne entity that I'm trying to fetch (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;
        }

        ....
    }

I set up my criteria and attempt to pull from the database using 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();

This gives me my Office but no Document if I have Bytecode Enhancement, and it gives me my Office and my Document if I DON'T have Bytecode Enhancement.

I'm at a loss. From what I can read in the documentation, I should have it set up correctly. I'm missing something, but I really don't know what it is. I have tried using the CriteriaBuilder as a test instead just to see if it made a difference, but the results were the same:

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

More confusing is that the generated SQL seems to be accurate. When I have a fetch, Hibernate shows the following:

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=?

Running that directly against my database gives me what I'm looking for in purely raw terms

Presently, I'm using Hibernate 5.4.2.Final, which as you can see includes Envers.

0

There are 0 best solutions below