Hibernate version: 3.0 RC1
I'm new to Hibernate. I've done plenty of reading of docs and got examples & test suites up and running. I'm in the initial process of creating the mapping configuration. In my application I have what I think is a fairly unusual set of relationships. I've read all of the 3.0 Reference Doc including a careful study of sections covering collections, relationships and inheritance mapping.
In my app I have Users and Roles (with a twist). Roles are members of a single Domain (<1=M> relationship). Users can subscribe to zero or more Roles and Roles can have zero or more subscribed Users (<M=M> relationship). This Role <=> User relationship is represented by a new RoleSubscription class so we now in fact have: Role <1=M> RoleSubscription <M=1> User. Each Role instance will contain an updateable map of RoleSubscriptions indexed by UserId. Each User instance will contain a map of RoleSubscriptions indexed by RoleId (optionally updateable).
All normal stuff so far ... now comes the first twist ...
Different roles may (optionally) require additional typed attributes to be associated with each Role subscription. So the RoleSubscription class can have subclasses that will contain the typed attributes as fields. One design concern here is that the RoleSubscription subclasses will redundantly imply the Role membership since a RoleSubscription derived class will correspond with a Role instance. In fact this is only partly correct, since some Roles will not have subscription attributes and thus will not require a RoleSubscription subclass. You might argue that the Role instances are redundant given that the RoleSubscription subclasses imply the Role, however Roles do exist as real entities even when no RoleSubscriptions exist and they also allow navigation to the Domain and management of User subscriptions. I'm not comfortable with this awkward design model but it might be the pragmatic solution.
And just to add some more spice ...
An indefinite number of new Role instances and associated RoleSubscription subclasses can be dynamically added during execution! Yes ... we do code generation of the subclasses and compilation at run-time. When new classes are added, Hibernate will need to update the DB tables via DDL and the Hibernate session will be need to be reconfigured. Thankfully this will not be too frequently. The important factor for the RoleSubscription inheritance mapping is
that the number of derived subclasses can be large.
Q1. What inheritance mapping would you recommend in this situation?
I think I'm leaning towards the solution in "Section 9.1.3 Table per subclass, using a discriminator" that will use a 1-1 join for each subclass. The discriminator (Role type) is required anyway to form the 1-M relationship between Role and RoleSubscription.
Given the potentially large number of derived classes, I want to try to avoid using UNION queries over an indefinite number of derived class tables. Hence I think I need to avoid the "Table per class hierarchy" method. Right?
The maps maintained in User and Role classes will hopefully only need to inspect the common RoleSubscription table only performing lazy loading when a subclass is loaded. Section 9.1.3 talks about using fetch="select" for this kind of lazy loading. Is my understanding correct?
Would you recommend a different inheritance mapping?
Q2. Are there any other issue that you think I need to consider for this scenario?
|