Ok, after spending several days, and reading chapter 8 more than twice, I'm still can't get this to work. I'm going to keep at it, and in the mean time, post the problem in the hopes that someone can provide some insight.
I'm building a security model, based on Users, Groups, Roles and Entitlemenents. The object relationship is as follows,
Code:
User(one)-----(many)Entitlement(many)-----(one)Group
(many)
|
|
(one)
Role
I chose to make Entitlement a component of User.
I need to support the following semantics,
o Save a new User, and the Entitlements should also be saved.
o Delete a User, and all associated Entitlements disappear, but all Groups and Roles remain.
o I'd like to be able to assign transient Roles and Groups, and have the engine either link to an existing Group/Role records or create a new Group/Role record (I don't know if Hibernate can handle this).
My (failed) attempt at mapping is as follows,
Code:
<class name=".User" table="USER">
<id column="ID" name="id">
<generator class="seqhilo">
<param name="sequence">SEC_SEQ</param>
<param name="max_lo">1</param>
</generator>
</id>
<property column="name" name="name"/>
<set cascade="all" name="entitlements" table="ENTITLEMENT">
<key column="USER_ID"/><!-- OR SHOULD THIS BE 'ID'? -->
<composite-element class="Entitlement">
<!--NOT SURE IF I NEED THIS--many-to-one cascade="save-update" name="user" column="USER_ID" class="User"/-->
<many-to-one cascade="save-update" name="group" column="GROUP_ID" class="Group"/>
<many-to-one cascade="save-update" name="role" column="ROLE_ID" class="Role"/>
</composite-element>
</set>
</class>
<class name="Entitlement" table="ENTITLEMENT">
<id column="ID" name="id"><!-- IS THIS NECESSARY? -->
<generator class="seqhilo">
<param name="sequence">SEC_SEQ</param>
<param name="max_lo">1</param>
</generator>
</id>
<many-to-one class="User" column="USER_ID" name="user"/>
<many-to-one class="Group" column="GROUP_ID" name="group"/>
<many-to-one class="Role" column="ROLE_ID" name="role"/>
</class>
<class name="Group" table="GROUP">
<id column="ID" name="id">
<generator class="seqhilo">
<param name="sequence">SEC_SEQ</param>
<param name="max_lo">1</param>
</generator>
</id>
<property column="name" name="name"/>
<set cascade="all" name="entitlements">
<key column="GROUP_ID"/>
<one-to-many class="Entitlement"/>
</set>
</class>
<class name="Role" table="ROLE">
<id column="ID" name="id">
<generator class="seqhilo">
<param name="sequence">SEC_SEQ</param>
<param name="max_lo">1</param>
</generator>
</id>
<property column="name" name="name"/>
<set cascade="all" name="entitlements">
<key column="ROLE_ID"/>
<one-to-many class="Entitlement"/>
</set>
</class>
I was able to get this working, as long as I only had 1 Entitlement in the Set, otherwise I got a unique constraint violation on the ENTITLEMENT primary key (ID).
My initial understanding was that cascading was a good idea. However, I've come up against many situations where cascading causeses problems. Maybe my initial assumption was wrong, and cascading should be used judiciously?
I have spent hours searching the Documentation, FAQs and Forums with no luck.
FWIW, This is my first attempt at Hibernate, so a validation of my approach would be benficial as well.
Thanks.
-Mitch