[hibernate-dev] HHH-11223 : Initialize bytecode enhanced lazy group using a single SQL statement

Steve Ebersole steve at hibernate.org
Fri Mar 2 17:24:19 EST 2018


Honestly I am not sure about whether they are "related".  I mean in 3949
the query sent to the database already does what you want it to do.

I theory 3949 should be easier to fix.  But what I find interesting there
is that NO_PROXY is requested but it seems as if proxies are still used.

On Fri, Mar 2, 2018 at 3:52 PM Gail Badner <gbadner at redhat.com> wrote:

> Steve, is this related to https://hibernate.atlassian.net/browse/HHH-3949?
>
> On Thu, Mar 1, 2018 at 10:11 PM, Gail Badner <gbadner at redhat.com> wrote:
>
> > This is not necessarily needed for 5.3.0, but I would like to get it into
> > the 5.3 branch.
> >
> > So far, there is one change to an SPI, Queryable#lazyGroupSelectFragment
> > is added:
> >
> > public String lazyGroupSelectFragment(
> > String tableAlias,
> > String suffix,
> > String fetchGroupName);
> >
> > The method gets implemented in AbstractEntityPersister.
> >
> > I don't think it's possible to create a default method in Queryable
> > because the method needs access to private/protect methods in
> > AbstractEntityPersister.
> >
> > If I don't get HHH-11223 in for 5.3.0, should I at least push the SPI
> > change for 5.3.0?
> >
> > On Thu, Mar 1, 2018 at 9:55 PM, Gail Badner <gbadner at redhat.com> wrote:
> >
> >> Hi,
> >>
> >> Currently, when a lazy group is loaded that has associations, there are
> 2
> >> SQL statements executed.
> >>
> >> For example, suppose the DEFAULT lazy group contains the following:
> >>
> >> * Order#customer is a lazy many-to-one association;
> >>
> >> * Order#text is a lazy LOB.
> >>
> >>
> >> When one of these properties is referenced, Hibernate loads both of
> them.
> >>
> >>
> >> Currently, it takes 2 SQL statements to get the association loaded.
> >>
> >>
> >> 1) Loads #text and the FK value for #customer (select o.text,
> >> o.customer_id from orders o where o.id = ?)
> >>
> >> 2) Loads the state for #customer (select ... from customers c where
> c.id =
> >> ?)
> >>
> >>
> >> In other words, FetchMode.SELECT is used to load associations in a lazy
> >> group.
> >>
> >>
> >> HHH-11223 involves combining the 2 SQL statements into a single
> >> statement using a join (i.e., using FetchMode.JOIN), but only when at
> least
> >> one of the following is true:
> >>
> >>
> >> * caching is disabled for the SessionFactory (e.g.,
> >> hibernate.cache.use_second_level_cache=false;
> >>
> >> * caching is not enabled for "get" operations (i.e.,
> >> session.getCacheMode().isGetEnabled() == false);
> >>
> >> * the associated entity type (and subclasses?) is not cached
> >>
> >> HHH-11223 only mentions to-one associations, but I think collections in
> a
> >> lazy group could also be loaded using a join as well.
> >>
> >> I think I'm pretty close, but I need to do a lot more testing to ensure
> >> it covers things like:
> >>
> >> * lazy association in composite ID
> >> * lazy association in an embeddable
> >> * lazy association in a secondary table
> >> * lazy association in a subclass
> >> * too many bags
> >>
> >> This is what I have implemented so far: https://github.com/hibern
> >> ate/hibernate-orm/pull/2170
> >>
> >> At the moment, I'm not looking for a comprehensive review. I'm just
> >> looking for a review of the overall design.
> >>
> >> I don't want to get into the nitty-gritty here, but, basically, I've
> >> created a new type of AbstractLoadPlanBasedEntityLoader,
> LazyGroupLoader,
> >> which loads the lazy group properties into the existing entity.
> >>
> >> If caching is disabled for the SessionFactory, then one loader is
> >> constructed per lazy group, and associations will be loaded using
> >> FetchMode.JOIN.
> >>
> >> If caching is enabled for the SessionFactory, then 2 loaders are
> >> constructed per lazy group. One loader is used when caching is enabled
> for
> >> "get" operations (using Fetch.SELECT for cached associated
> >> entities/collections; Fetch.JOIN for other associations). The other
> loader
> >> is used when caching is disabled for "get" operations.
> >>
> >> Here are some of the changes to the default behavior (described above)
> >> that could be useful:
> >>
> >> 1) Change all associations in lazy groups to be loaded using
> >> FetchMode.SELECT (as is currently done without the fix), or using
> >> FetchMode.JOIN (regardless of caching). A new configuration property
> could
> >> be added:
> >>
> >> hibernate.bytecode.lazyGroup_association_fetchMode=(default | select |
> >> join )
> >>
> >> 2) Allow the FetchMode to be configured for a particular lazy
> >> association. According to the documentation [1], @Fetch can't be used
> for
> >> this because,  "... FetchMode.JOIN acts as a FetchType.EAGER strategy.
> Even
> >> if we mark the association as FetchType.LAZY, the FetchMode.JOIN will
> load
> >> the association eagerly."
> >>
> >> A new annotation could be introduced: @LazyFetch.
> >>
> >> Comments or suggestions?
> >>
> >> Thanks,
> >> Gail
> >>
> >> [1] http://docs.jboss.org/hibernate/orm/5.2/userguide/html_s
> >> ingle/Hibernate_User_Guide.html#fetching-fetchmode-join
> >>
> >
> >
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>


More information about the hibernate-dev mailing list