Hibernate XML Mapping: Lazy False or Fetch Select?

chris picture chris · Dec 7, 2010 · Viewed 67.3k times · Source

I have a simple question. I found this Hibernate config on our project:

<many-to-one name="employee" 
    class="com.myapp.Employee"
    cascade="merge"
    lazy="false"
    fetch="select">
<column name="employee_id"
     sql-type="bigint" 
     not-null="true"/>
</many-to-one>

Doesn't fetch="select" mean "Lazy load all the collections and entities" based on Fetching Strategies. But by writing lazy="false" mean do not lazy load. So the config above says: "Disable lazy loading. Enable lazy loading." In effect, this means the property is lazy loaded?

So I could shorten that config as:

<many-to-one name="employee" 
    class="com.myapp.Employee"
    cascade="merge"
    fetch="select">
<column name="employee_id"
     sql-type="bigint" 
     not-null="true"/>
</many-to-one>

But isn't fetch="select" the default mode? So in effect, I can declare the same config as:

<many-to-one name="employee" 
    class="com.myapp.Employee"
    cascade="merge">
<column name="employee_id"
     sql-type="bigint" 
     not-null="true"/>
</many-to-one>

Am I correct? Wrong? Ideas? Thanks

If I want to enable lazy loading, I must add lazy="true" and remove lazy="false"?

Answer

octav picture octav · Dec 7, 2010

I think Fetch Mode and time of fetch are concepts that don't totally overlap.

Lazy="true|false" controls whether an association is loaded eagerly or on demand.

fetch="select|subselect|join|batch" controls how is that entity or collection loaded, when it's required to be loaded.

So, to answer your question, having fetch="select" means:

"a second SELECT is used to retrieve the associated entity or collection. Unless you explicitly disable lazy fetching by specifying lazy="false", this second select will only be executed when you access the association." (http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-fetching)

This doesn't mean that lazy loading is disabled! That's controlled by the lazy="true|false" flag. With lazy="true" and fetch="select" Hibernate will lazy load the collection and will load it with a select. If you set lazy="false", the same select will be executed, the difference will be that it will get executed eagerly. Hope this makes sense.

Have a look here as well: http://community.jboss.org/wiki/AShortPrimerOnFetchingStrategies