I am trying to make some of my many-to-one relationships in my hibernate HBM files lazy. Concretely I have a DataElement class that references the Filter element in a many-to-one relation, I want to make it lazy while keeping access to Filter eager in other parts of the application.
I have tried changing my HBM files and found that the lazy="true" is only available at the class level
DataElement's mapping (I want the many-to-one with filter to be lazy)
<hibernate-mapping package="project.me" default-lazy="false" auto-import="false">
<class name="DataElement" table="DATA_ELEMENT">
<id name="id" type="java.lang.Long" column="ID"/>
<many-to-one name="filter" class="project.me.Filter" column="FILTER_ID" cascade="all"/>
</class>
</hibernate-mapping>
FilterAudit's mapping (I want the many-to-one with filter to be eager)
<hibernate-mapping package="project.me" default-lazy="false" auto-import="false">
<class name="FilterAudit" table="FILTER_AUDIT">
<id name="id" type="java.lang.Long" column="ID"/>
<many-to-one name="filter" class="project.me.Filter" column="FILTER_ID" cascade="all"/>
</class>
</hibernate-mapping>
Filter's mapping
<hibernate-mapping package="project.me" default-lazy="false" auto-import="false">
<class name="Filter" table="FILTERS" lazy="true">
<id name="id" type="java.lang.Long" column="M_ID"/>
<property name="type" type="filterType" column="M_FILTER_TYPE"/>
<many-to-one name="predicate" class="Predicate" column="PRED_ID" unique="true" not-null="true" cascade="all"/>
</class>
</hibernate-mapping>
By putting lazy="true" at the Filter class's level, I make all the DTOs in the application load Filter lazily and I don't want that
Is there a way to specify the lazy load only for the relation between DataElement and Filter while keeping the load between FilterAudit and Filter eager ?
My recommendation: Do not use eager fetching. It results in inconsistency and sometimes weird queries. Furthermore, it is difficult to optimise the performance when you use eager fetching. In the mentioned case, I would create different methods to call the database with some fetch joins or entity graphs.
I do not use HBM (or other XML based mapping). I use annotations why I cannot provide you with an answer with XML mapping (HBM seems to be outdated anyway).
My preferred way is using the JPA Criteria API instead of JPQL. Some people say that JPQL is better understandable but I prefer the type-safe Criteria API which is less error prone. I prefer entity graphs because they are easier to use dynamically than fetch joins. Nevertheless, the other options work as well.
At first, I would set up the entity classes appropriate to Vlad Mihalcea's article. (I infer a unidirectional relationship.)
Similar for
FilterAudit(alsoFetchType.LAZY)...And then
Filter(not that interesting because it is unidirectional).Now, the relevant part for initialising the lazy loads (or not) gets realised in this case with the JPA Criteria API and entity graphs.
For retrieving an object of the same class without its relationship, just omit the entity graph.