-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Ternary associations - Many-to-Many-to-Many
PostPosted: Fri Dec 05, 2008 11:59 am 
Newbie

Joined: Fri Dec 05, 2008 11:31 am
Posts: 6
Hello,

I have read the documentation about the ternary associations

http://www.hibernate.org/hib_docs/v3/re ... ns-ternary

but the two hbm examples do not exactly apply to us (although the second one is very close). In our case we need association many-to-many between three objects so that any of the three objects can have either set of pairs of any combination of the other two objects or a map in which the key is the second object and the value is a set of the third objects (more explanation below).

The example in the link provided creates a map where the key is the second object but the value is a single third object (instead of the set of third objects).

To be precise, the three types of objects are: users, roles and sites. One user has multiple roles for each site. One role has multiple users for each site. One site has multiple users for each role.

Therefore, we need to implement methods for each combination:
User.getRolesForSite(Site) - get a list of roles the user has in the given site
User.getSitesForRole(Role) - get a list of sites in which the user has given role
Role.getUsersForSite(Site) - get a list of users that have the role in given site
Role.getSitesForUser(User) - get a list of sites in which the given user has the role
Site.getUsersForRole(Role) - get a list of users with given role in the site
Site.getRolesForUser(User) - get a list of roles the given user has in the site

In the database we have a table with three columns: userId, roleId and siteId which are foreign keys to tables that represent each domain object.

We do not want to create a separate domain object that would hold these relations (UserRoleSite).

The question is:
Is there an hbm configuration we could apply that would be able to stand for this type of relation? Like I mentioned before, the documentation

http://www.hibernate.org/hib_docs/v3/re ... ns-ternary

(the second example) provides a solution that is a very close to what we want, with the only difference that the documentation example gives IncomingNode.Map<Node, Connection>, which would be converted to our example: Sites.Map<Role, User>, while what we need is an example that would give IncomingNode.Map<Node, Set<Connection>>, which would be converted to our example: Sites.Map<Role, Set<User>>.

Thank you. Please help. Please let me know if I was not clear enough.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 4:15 pm 
Newbie

Joined: Sun Sep 07, 2008 11:07 pm
Posts: 17
I am having the same kind of object model. Did you find any solution?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 19, 2009 4:33 pm 
Newbie

Joined: Fri Dec 05, 2008 11:31 am
Posts: 6
We ended up creating a domain object RoleUserSite and let each type have a set of these objects. After all, it is not that bad way.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 20, 2009 3:44 pm 
Newbie

Joined: Sun Sep 07, 2008 11:07 pm
Posts: 17
Thanks for the quick response.

The class would be something like this

Public class User{
List RoleUserSite;
...
}

But this List is going to give List of Role and Site for a given user.
Something like this
[Role1, site1
Role2, site2
Role1, site3
]

So how do we figure out all the Sites for a given Role and a User i,e this method User.getSitesForRole(Role)
Do we need to loop around the entire List and figure it out?


Please Reply

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 20, 2009 4:17 pm 
Newbie

Joined: Fri Dec 05, 2008 11:31 am
Posts: 6
There are two ways to do it. One is the loop mentioned by you:

class User
{
List<RoleUserSite> roleUserSites;

List<Site> getSitesForRole(Role role)
{
List<Site> sites = new ArrayList<Site>();
for(RoleUserSite roleUserSite:roleUserSites)
if (roleUserSite.getRole().equals(role)
sites.add(roleUserSite.getSite());
return sites;
}
}

or another way is to use a hibernate query that would look something like this:

"select s from Site s left join s.roleUserSites rus where rus.user.id=:userid and rus.role.id=:roleid"

Please keep in mind that I actually didn't test the code above so it might have some problems, but it is just to give you an idea of how this could be implemented.

The first method is a one level loop in the memory which is quite fast and the second method is a single database query which is fast as well.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 20, 2009 8:09 pm 
Newbie

Joined: Sun Sep 07, 2008 11:07 pm
Posts: 17
Thanks for the update


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.