Don't ever forget to specify 'inverse="true"' on a one-to-many or many-to-many relationship! I ended up forgetting this in most of my mappings, and finally caught it when creating a new report. I fetched a list of users, then iterated through the users and fetched associated objects that met certain parameters. What ended up happening, was when I went to fill the set of associated objects, if there were none, it wiped out all foreign keys mapping any matching objects (even outside my defined parameters) linking them to the user.
I went back and specified the inverse parameter on all my mappings. With any luck, this resolves a nasty bug I've had trouble tracking that was removing my user to group associations.
<set name="kittens" table="KITTENS" lazy="true" batch-size="25" inverse="true"> <key column="PARENT" /> <one-to-many class="com.example.Kitten" /> </set>
Here, many kittens can have a parent. The inverse is always specified with the one-to-many relationship mapping.
<set name="groups" table="USER_GROUP" lazy="true" batch-size="25" inverse="true"> <key column="USER_ID"/> <many-to-many column="GROUP_ID" class="com.example.Group"/> </set>
In a many-to-many relationship, the inverse property can be specified in either side of the mapping.
There is more good info in the first below-linked reference regarding some defensive programming techniques. I'll be studying it.