Skip to content

Proposal LoadPlans

Steve Ebersole edited this page Jul 23, 2013 · 1 revision

The idea behind a LoadPlan is to generically describe the pieces of information needed to build a SQL SELECT query and to build a delegate capable of processing the results of said SELECT query. The general contract of a LoadPlan is defined by the org.hibernate.loader.plan.spi (currently named org.hibernate.loader.plan2.spi). LoadPlans are built in 2 distinct pieces.

QuerySpaces

First we have the concept of a series of org.hibernate.loader.plan2.spi.QuerySpace instances. A QuerySpace describes a reference to a persister or composite value. They serve much the same purpose as a FromElement in the HQL parser or what JPA calls an "abstract schema type" when describing JPQL/Criteria queries. Their SQL corollary would be table references in the FROM-clause.

A QuerySpace is intended to provide unified access to metadata information for a particular type. It also exposes a unique id (a uid) so that other parts of a LoadPlan may refer to it. It also exposes the org.hibernate.persister.entity.PropertyMapping for the space which is useful to resolve information about properties and their SQL column/formula fragments, etc.

A QuerySpace also exposes any joins in contains (as a org.hibernate.loader.plan2.spi.Join). These joins do not necessarily have any correlation to SQL joins; they are just a conceptualization.

Depending on the specific type of QuerySpace, additional information may be exposed.

Returns/Fetches

Returns (org.hibernate.loader.plan2.spi.Return) and fetches (org.hibernate.loader.plan2.spi.Fetch) describe things to be selected (they describe the width of the ResultSet, if you will). A Return is distinct from a Fetch in that a Return is a root return of the load, whereas a Fetch is just data fetched into a Return or another nested Fetch.

There are 3 types of Returns: ScalarReturn (only used in HQL/Criteria scenarios), EntityReturn and CollectionReturn. EntityReturn and CollectionReturn may additionally contain Fetch graphs.

Building LoadPlans

It is expected that eventually HQL and Criteria query translations will produce LoadPlans, which are used to build ResultSetProcessors. We could generate SQL too in those cases, but would have to make LoadPlan understand about restrictions, orderings, groupings, etc. Dunno if that part if worth the effort. We could have a hybrid approach where the HQL and Criteria query translators use LoadPlans to render the SQL SELECT and FROM clauses, but still render the rest of the SQL on their own. Anyway this is all under consideration.

Currently the only approach to building a LoadPlan is via the new association walking SPI. This handles entity loading (Session#get, including batch fetching) and collection initializers, EntityReturn and CollectionReturn respectively. org.hibernate.loader.plan2.build.spi.MetamodelDrivenLoadPlanBuilder is the main entry point into this approach. It walks the association tree as defined by org.hibernate.persister.walking package. As it walks the associations, it calls out to the org.hibernate.loader.plan2.build.spi.LoadPlanBuildingAssociationVisitationStrategy it is passed. The LoadPlanBuildingAssociationVisitationStrategy builds the LoadPlan in response to those calls. This LoadPlan is then handed to a org.hibernate.loader.plan2.exec.spi.LoadQueryDetails object which interprets the LoadPlan into SQL and a org.hibernate.loader.plan2.exec.process.spi.ResultSetProcessor

TODO

Should propose and document the specific structure of a LoadPlan