Hibernate 3.2.5 GA on Mysql 5.
I've found that the following subject is very difficult to search for, only because the key words are so pervasive.
Basically I've got the following model.
Users
Groups
UserToGroup (Group Memberships)
Where UserToGroup's schema looks something like: userId, groupId, association-property1, index (I've mapped the memberhips with a List and want them sorted on the value, it's a user specified "priority"). (userId, groupId) is the PK.
In other words, my requirement is to add properties to a many-to-many association mapping and map them to a Java object.
The hibernate reference manual and the official hibernate book both suggest doing this with a composite-element on a collection, but go on to say that you can't do shared references. I assume this is because of some never ending lazy loading = false catastrophe that might occur. (Please correct me if I'm off).
So I went ahead and tried that, and everything worked great... until I realized I needed the shared reference to the collection's key so that my hashcode and equals functions would make sense. (i.e. the PK=business key) Plus, it would be kinda nice to have that anyway ...
To top it off, I then realized having the List's index value would be useful as well since my comparator class would need it to do sorting etc.
BUT ... neither are exposed via the "normal" mapping as described in the reference material.
So after toying around a bit(read: scouring the interwebs, printed references and experimentation), I eventually figuired out that I could use the formula feature to pull both the collection's key and the index value of the list of out of the join table!
I feel like I beat the system... (Again... correct me if I'm wrong)
How else can we map such a data model? There's got to be a more elegant way to go about this....
Here's the relevant code to put all of the above rant into something legible:
Code:
public class UserToGroup implements Serializable;
{
private Group group;
private Long rogueUserId;
private Integer index;
private Boolean someProperty;
....
<insert getter/setters>
....
public boolean equals(Object o)
{
if (o == null || !( o instanceof UserToGroup)
return false;
else
{
UserToGroup other = (UserToGroup)o;
if (other.getGroup.equals(this.getGroup) && other.getRogueUserId().equals(this.getRogueUserId()))
return true;
else
return false;
}
}
public int hashcode()
{
//Similiar to the equals above, I need both parts of the PK for it to make sense.
}
}
<class name="User">
<list lazy="false" name="groupMemberShips" table="OfficerToCampus">
<key column="userId" />
<list-index column="index" />
<!-- Niether of the above gets mapped to member vars in the java class -->
<many-to-one name="group" column="groupId" not-null="true" Class="Group" lazy="false" />
<composite-element class="UserToGroup">
<property name="someProperty" />
<!-- Is the below cheating? Is there a cleaner way? -->
<property name="index" formula="index" />
<property name="rogueUserId" formula="userId" />
</composite-element>
</list>
<!-- more properties and the id below -->
</class>
Thanks for taking the time to read my post.... I'm eager to here some opinions on the above. Happy holidays!
CS