All,
Please consider the following scenario which I'm implementing using
Hibernate 3.0.5 on
Oracle 10g:
Code:
<class name="Merchant" table="MERCHANT" lazy="false">
<cache usage="read-write"/>
<set name="warehouseAddresses" table="LINKMERCHANTADDRESS" lazy="true" cascade="none" sort="unsorted">
<key column="MERCHANTID" foreign-key="LMA_MERCHANTID_FK"></key>
<many-to-many class="com.comerxia.core.model.Address" column="ADDRESSID" outer-join="auto" foreign-key="LMA_ADDRESSID_FK"/>
</set>
</class>
Code:
<class name="Address" table="ADDRESS" lazy="true" discriminator-value="null">
<subclass name="com.comerxia.core.model.WarehouseAddress" lazy="true" discriminator-value="WAREHOUSE">
<property name="code" type="java.lang.String" update="true" insert="true" column="CODE" unique="true"/>
</subclass>
</class>
Notice that Merchant has a Set (many-to-many) of Addresses. Merchant is not lazy, but the set is intended to be. Address does have a polymorphically mapped subclass, WarehouseAddress.
When I load a Merchant, the set of Addresses is fetched eagerly using a select (N+1, in fact). No matter what I do (played with lazy/!lazy, etc.), I cannot get the many-to-many to lazy-load.
I am convinced that this is something I'm doing wrong, but I can't find the explanation in the docs, nor can I come up with a scnenario that causes the lazy="true" declaration to be obeyed. Debug level logging during the fetch of Merchant reveals that Hibernate is classifying this as a non-lazy collection. The Set is actually PersistentSet at runtime, and the populated Address beans are actually proxies. So the system is providing me with the correct implementations, but it is initializing the set prematurely. If I make Merchant lazy="true", the whole Set is initialized with the first call to any Merchant property.
I'm going to attack this by (correctly, I think), unmapping the set from Merchant and simply querying for the Addresses when I need them, but I still don't have the answer as to why this isn't working for me.
Any ideas?
-Chris