I have a company hierarchy of divisions represented as nested sets, stored in one self-joined table (HBM excerpt below). I want to retreive the hierarchy and serialize it to XML (to display in a web app via XSLT). I can get all the necessary data by doing one simple select that retreives all divisions of one company, and Hibernate should know how to make a hierarchy out of it.
However, there are problems.
The first one is that the subdivisions collections remain uninitialized (I have lazy everywhere because otherwise every query fetches the entire database), so I get an extra select for every division's subdivisions, although all the necessary data had already been fetched with that one select. I understand that the collection has no way of knowing that, because the initial query just fetches the divisions with no mention of subdivisions... But nevertheless, the data IS there. Is there any way to tell the collection to just behave as if it was (properly) initialized?
And this wouldn't even be such big a problem (performance is currently the last of my worries ;)) if my serializer (XStream with some customization) wasn't programmed to skip uninitialized collections (which is what I want and the reason I even use lazy).
I tried some other approaches, including using DOM4J entity mode to generate XML, but I found that it doesn't offer much control over what to fetch and what to include in XML. (Is there any way to set the embed-xml property on a per-query basis?)
So, how does one properly initialize nested collections? Or if you know any way get where I'm going...
Thanks and regards,
Jaka
-------
Hibernate version: 3.0.5
Mapping documents:
Code:
...
<union-subclass name="DivisionImpl" table="DIVISION">
<property name="name" type="java.lang.String">
<column name="NAME" not-null="true" unique="false"/>
</property>
<set name="subdivisions" order-by="PARENT_FK" lazy="true" fetch="select" inverse="true" cascade="all-delete-orphan">
<key foreign-key="DIVISION_PARENT_FKC">
<column name="PARENT_FK"/>
</key>
<one-to-many class="DivisionImpl"/>
</set>
<many-to-one name="parent" class="DivisionImpl" fetch="select" cascade="none" foreign-key="DIVISION_PARENT_FKC">
<column name="PARENT_FK" not-null="false"/>
</many-to-one>
<many-to-one name="company" class="CompanyImpl" fetch="select" cascade="none" foreign-key="DIVISION_COMPANY_FKC">
<column name="COMPANY_FK" not-null="true"/>
</many-to-one>
</union-subclass>
...
Code between sessionFactory.openSession() and session.close():Code:
session.createQuery("from DivisionImpl where company = :company")
.setEntity("company", company)
.list();
Name and version of the database you are using: PostgreSQL 8.0.3
The generated SQL (show_sql=true):Code:
select divisionim0_.ID as ID, divisionim0_.NAME as NAME34_, divisionim0_.PARENT_FK as PARENT2_34_, divisionim0_.COMPANY_FK as COMPANY3_34_ from DIVISION divisionim0_ where divisionim0_.COMPANY_FK=?
[/code]