Hi, I'm using Hibernate 2.1.2 and the latest release of middlegen with postgres 7.4.1. I have had query generation problems in hibernate with composite keys, and the solution is clearly stated in the Hibernate FAQ
http://www.hibernate.org/74.html#A3 -- columns for composite keys need to be in the same order inside composite-id, set, and many-to-one tags. Middlegen does not produce such universal orderings; once I hand-corrected my middlegen-generated XML files to respect such ordering my query problems disappeared.
I've taken a look at the hibernate.vm file in the middlegen CVS tree, and sure enough in composite-id tags an algorithm of non-relationship columns following each set of columns in relationships determines the ordering. For set and many-to-one tags, the built-in columnMaps of roles are used, and doesn't use the same more-complex ordering policy used in composite-id.
One solution would involve adding some mechanism that orders columns from columnMaps in roles just like the composite-id ordering that happens in hibernate.vm, but that would inelegantly put an ordering algorithm in Java that would need to maintain consistency over time with the state of the vm file. yuck. The alternative of doing extra work in composite-id to agree with columnMap orderings is complicated by ordering constraints in the tag structure. Anyone with better knowledge of the code have a an idea for a good fix? I've posted my middlegen hbm.xml files below -- the problem is that CUDestinations composite-id tag first mentions destinationcomponentid and then componentupdateid, while elsewhere componentupdateid precedes destionationcomponentid. Thanks!
-alan
PS. I think the real answer to this problem is that Hibernate shouldn't be so picky about column ordering, since it can reorder columns into SQL queries at will, but in the meantime, middlegen should deal appropriately...
--------------
ComponentUpdate.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->
<class
name="context.arch.logging.hibernate.ComponentUpdate"
table="componentupdate"
>
<id
name="componentupdateid"
type="java.lang.Integer"
column="componentupdateid"
>
<generator class="assigned" />
</id>
<property
name="componentid"
type="java.lang.String"
column="componentid"
not-null="true"
length="-1"
/>
<property
name="updatetime"
type="java.sql.Timestamp"
column="updatetime"
not-null="true"
length="8"
/>
<property
name="updatename"
type="java.lang.String"
column="updatename"
not-null="true"
length="-1"
/>
<!-- associations -->
<!-- bi-directional one-to-many association to CUDestination -->
<set
name="CUDestinations"
lazy="true"
inverse="true"
>
<key>
<column name="componentupdateid" />
</key>
<one-to-many
class="context.arch.logging.hibernate.CUDestination"
/>
</set>
</class>
</hibernate-mapping>
CUDestinations.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->
<class
name="context.arch.logging.hibernate.CUDestination"
table="cudestinations"
>
<composite-id name="comp_id" class="context.arch.logging.hibernate.CUDestinationPK">
<key-property
name="destinationcomponentid"
column="destinationcomponentid"
type="java.lang.String"
length="-1"
/>
<!-- bi-directional many-to-one association to ComponentUpdate -->
<key-many-to-one
name="ComponentUpdate"
class="context.arch.logging.hibernate.ComponentUpdate"
>
<column name="componentupdateid" />
</key-many-to-one>
</composite-id>
<property
name="success"
type="java.lang.Boolean"
column="success"
length="1"
/>
<!-- associations -->
<!-- bi-directional one-to-many association to CUAttribute -->
<set
name="CUAttributes"
lazy="true"
inverse="true"
>
<key>
<column name="componentupdateid" />
<column name="destinationcomponentid" />
</key>
<one-to-many
class="context.arch.logging.hibernate.CUAttribute"
/>
</set>
</class>
</hibernate-mapping>
CUAttributes.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->
<class
name="context.arch.logging.hibernate.CUAttribute"
table="cuattributes"
>
<composite-id name="comp_id" class="context.arch.logging.hibernate.CUAttributePK">
<key-property
name="attributename"
column="attributename"
type="java.lang.String"
length="-1"
/>
<!-- bi-directional many-to-one association to CUDestination -->
<key-many-to-one
name="CUDestination"
class="context.arch.logging.hibernate.CUDestination"
>
<column name="componentupdateid" />
<column name="destinationcomponentid" />
</key-many-to-one>
</composite-id>
<property
name="attributetype"
type="java.lang.String"
column="attributetype"
not-null="true"
length="-1"
/>
<property
name="attributevaluestring"
type="java.lang.String"
column="attributevaluestring"
length="-1"
/>
<property
name="attributevaluenumeric"
type="java.lang.Float"
column="attributevaluenumeric"
length="4"
/>
<!-- associations -->
</class>
</hibernate-mapping>