Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why arrays cannot be lazy-loaded in a one-to-many assocation?

According to Hibernate documentation :

After observing that arrays cannot be lazy, you can conclude that lists, maps and idbags are the most performant (non-inverse) collection types

So my question is dead simple : why arrays cannot be lazy-loaded in a one-to-many assocation ?

like image 346
fabien7474 Avatar asked Jun 17 '12 10:06

fabien7474


1 Answers

Lazy load works by the fact that Hibernate uses structures that can be proxied to know when you try to access the data for the first time. When you do this, these structures will tell hibernate that they now need to load the information and Hibernate will then do this on-the-fly, without you knowing what's happening.

Arrays can't be lazy loaded because Hibernate wouldn't have a way to know you are trying to access them for the first time, since you can't proxy the "[]" operator ( the aaload bytecode ), Hibernate would never know when you first tried to access it so it would not be able to load it on the fly.

When using collections, you always have to access them through their methods, so Hibernate can be 100% sure when you're trying to access them for the very first time and then load them.

So, the real reason is that there is no way to hook your code to the array access operator. The same happens on lazy loading for fields, Hibernate can't lazy load a non-collection property with field only access as it wouldn't know when you tried to access the field, they always need to have get/set method access.

As an example of how this is done, you can check the PersistentList collection on Hibernate, on it's indexOf method (and many others) the read method is called:

public int indexOf(Object value) {
    read();
    return list.indexOf(value);
}

And in the end the read method just initializes the collection if it hasn't been lazy loaded yet.

like image 160
Maurício Linhares Avatar answered Oct 05 '22 23:10

Maurício Linhares