Probably this is a 'Hibernate usage questions and discussions' post:
Hibernate version: 3.0.1
Name and version of the database you are using: MSSQL 2000
I have three classes: User, Account, Location. Each user has some accounts, each account has some locations, but each user can only see defined locations. So I have 6 many-to-many associations.
But when I wan't to show this object graph as it defined (with all three many-to-many used) I have to evict objects before removing locations that user cannot see (despite their account parent) - in order not to loose my account-location association (dirty check removal).
Is there a better way to do this?
I'm having a filter solution in mind, where each object would hold a permission field. So only objects with certain permission would get loaded.
What about usage in Hibernate2?
Since I use the same structure in application which still uses H2.
Can something additional be told in mappings?
Code between sessionFactory.openSession() and session.close():
Criteria criteria = fromUsernamePassword(session);
criteria.setFetchMode("accounts", FetchMode.EAGER);
User user = (User)criteria.uniqueResult();
applyLocations(user, session);
private void applyLocations(User user, Session session) throws HibernateException {
if (user != null) {
//certain user sees only his mapped locations
//seen locations on account depend on different users!
Iterator iter = user.getAccounts().iterator();
while (iter.hasNext()) {
Account account = (Account)iter.next();
SortedSet accoutLocations = account.findLocations(user);
//Change applied with upper method must not change account relations.
//If evicted, changes to the instance will not be synchronized with the database.
session.evict(account);
account.setLocations(accoutLocations);
}
}
}
Mapping:
User:
<set
name="locations"
table="userlocation"
lazy="true"
inverse="false"
cascade="none"
sort="unsorted"
>
<key
column="user_id"
>
</key>
<many-to-many
class="com.generalynx.common.userdata.LocationData"
column="location_id"
outer-join="auto"
/>
</set>
<set
name="accounts"
table="useraccount"
lazy="true"
inverse="false"
cascade="none"
sort="natural"
>
<key
column="user_id"
>
</key>
<many-to-many
class="com.generalynx.gema.utils.data.Account"
column="account_id"
outer-join="auto"
/>
</set>
Account:
<set
name="users"
table="useraccount"
lazy="true"
inverse="true"
cascade="none"
sort="unsorted"
>
<key
column="account_id"
>
</key>
<many-to-many
class="com.generalynx.gema.utils.data.User"
column="user_id"
outer-join="auto"
/>
</set>
<set
name="locations"
table="accountlocation"
lazy="true"
inverse="false"
cascade="none"
sort="natural"
>
<key
column="account_id"
>
</key>
<many-to-many
class="com.generalynx.common.userdata.LocationData"
column="location_id"
outer-join="auto"
/>
</set>
Location:
<set
name="accounts"
table="accountlocation"
lazy="true"
inverse="true"
cascade="none"
sort="unsorted"
>
<key
column="location_id"
>
</key>
<many-to-many
class="com.generalynx.gema.utils.data.Account"
column="account_id"
outer-join="auto"
/>
</set>
<set
name="users"
table="userlocation"
lazy="true"
inverse="true"
cascade="none"
sort="unsorted"
>
<key
column="location_id"
>
</key>
<many-to-many
class="com.generalynx.gema.utils.data.User"
column="user_id"
outer-join="auto"
/>
</set>
Any thoughts on this?
Ales
|