Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Teneo/Hibernate/Collection Extra-Lazy Loading

As a default collections are lazy loaded, this means that a collection is loaded in memory when it is first accessed but not before. There are collections which are to large to load in memory for standard operations. For these collections it can make sense to make use of the Hibernate extra-lazy functionality. Teneo supports this functionality and facilitates making use of it.

See this blog for some information on Hibernate extra-lazy behavior.

Hibernate only supports extra-lazy loading for lists which are bi-directional and have an explicit property/member for the list-index. Teneo makes it possible to also use the Hibernate extra-lazy mode for uni-directional associations when the list-index is not mapped. Teneo does this by creating so-called synthetic properties which take care of storing this information.

With extra-lazy handling the following operations are being executed by individual calls to the database (instead of loading the complete collection in memory):

  • append
  • remove last element in the list
  • get
  • set
  • contains
  • size

Enabling Extra-Lazy Mapping

Extra-lazy handling can be enabled in two ways:

  • By setting the option PersistenceOptions.FETCH_ASSOCIATION_EXTRA_LAZY
  • By setting the fetch attribute of the OneToMany annotation to EXTRA: @OneToMany(fetch=EXTRA)

The first option sets extra-lazy for all one-to-many associations, the annotation is useful for when selecting extra-lazy for specific associations.

LazyCollectionUtils

Teneo provides a special utility class for lazy handling of a collection. These utility methods work for both extra-lazy collections as well as collections which are not extra-lazy. The class is: org.eclipse.emf.teneo.hibernate.LazyCollectionUtils. This class offers two utility methods:

  • size: this method performs a database count to determine the collection size (instead of loading the collection into memory)
  • getPagedLoadingIterator: this method returns an iterator (over a collection) which loads the data from the collection in pages from the database. While iterating old pages of data are discarded and new ones are read from the database.

Choosing an Alternative Mapping

Another approach (than using extra-lazy) is to choose another mapping approach.

When you encounter a very large collection in your model then you can also decide to not explicitly map this collection to the database but map the 'other side'.

So assume that you have a type called 'Root' which has a collection efeature 'leafs' with thousands of children (the 'Leaf' type). Instead of mapping the collection to the database it can be an option to only map the reference from Leaf to Root (so from child to parent). The Root.leafs collection can then be made transient (using a @Transient annotation). Then when working with the data in your application you can query directly for specific Leaf objects using a Root object as the filter.

Back to the top