Skip to content

Proposal Loader redesign

sebersole edited this page Feb 20, 2013 · 5 revisions

Loader is an internal contract. The basic idea is that it builds SQL, prepares the Statement and processes the resulting ResultSet. To do that it follows the common legacy Hibernate pattern of class hierarchies; so there is a specific Loader impl for loading from a HQL query or batch loading or native-sql query or ... Al in all pretty inflexible.

What I envision here instead is Loader as a basic "coordination contract" which takes a ResultSet and a LoadPlan and knows how to process the ResultSet in terms of said LoadPlan. Currently LoadPlan does not exist, although to a degree it is a function of the current contract between the base Loader class and its subclasses. That just needs to be cleaned up and formalized.

The reasoning here is that this would allow better reuse of instances. LoadPlans could be built:

  • statically from result-set-mapings, HQL specifications, etc
  • dynamically based on fetch profiles etc

Also the LoadPlan would remain the same whether we are batching or not, how many ResultSets we are processing (think chained ResultSets or procedure cursor output params)

Considerations

List of things to consider in implementing:

  • scrollable results + collection fetching should cause fetching to be done subsequently (subselect, etc). That is to allow unification of the concepts of (a) load a row, (b) load a row sequentially and (c) load a row sequentially n reverse. However, scrollable results + collection fetching + locking could be problematic
  • paging + collection fetching should automatically cause fetching to be done subsequently (subselect, etc). This allows the paging numbers to refer to the number of results ultimately returned to the user rather than the number of SQL results, which is a more natural expectation
  • better overall handling for follow-on locking
  • I really like the idea of org.hibernate.loader.spi.AbstractResultProcessor.SubSelectFetchHandler for handling "follow on" stuff. The general idea is a delegate which exposes 2 callbacks: one called as we process each row, and a second called after we are all done. This pattern fits for both subselect fetching and follow-on locking. For that to work fully, would need to expand the current API there a bit to allow correlation during first callback between entity/collection and its corresponding return/fetch.
  • Part of the process here is replacing the JoinWalkers with a true "visitor" approach. A potential improvement building off of that in terms of start up performance would be to simultaneously perform the multiple walkings of an entity tree in the same call (by passing multiple visitation strategies). If workable, could be a big perf win.

Proof-of-concept work is housed at https://github.com/sebersole/hibernate-loader-redesign

Jira is at https://hibernate.onjira.com/browse/HHH-7841

More to come...