I'm using Hibernate version 3.0 Final.
I'm new to Hibernate but in the past I've built an O/R mapping layer for another product that supports a feature I've not seen in Hibernate 3.0 - or at least not yet figured out how to use. So this is either a suggestion or a request for advice.
What
I think is lacking in Hibernate is that all collections appear to require a foreign key; in other words they must be part of an association. Right?
What I want to do is to be able to navigate an entire object model via a single top level 'Model' class that exposes a small number of collections (much like foriegn key association collections) that span an entire table (no foreign key filter). For example, suppose we have User and Group objects and a bidirectional association between them. The User and Group classes both have Id and Name properties. Our Model class might expose Users and Groups Map collections indexed by their Name. We can use these collections to Add/Remove User and Group objects and find them by Name.
Like their foreign key linked cousins, I use these top level collections to add/remove and retrieve elements (typically via a Map collection key) the difference being that they control an entire table rather than just a subset of objects filtered by a foriegn key. The Model class gives the illusion that the entire object model is in memory. It works because the O/R mapping engine is smart enough to not retrieve the entire collection - particularly when only a single element is requested (lazy loading). Hibernate's support for paginated loading futher mitigates any performance concern with exposing an enitire table as a collection.
The single Model class can in some circumstances replace or at least reduce the number of traditional DAO layer classes.
Code:
class Model
{
private Map users;
private Map groups;
// Get/Set ALL users in the database indexed by User.getName()
public Map getUsers() { return users; }
private void setUsers(Map users) { this.users = users; }
// Get/Set ALL groups in the database indexed by Group.getName()
public Map getGroups() { return groups; }
private void setGroups(Map users) { this.groups = groups; }
}
class User
{
private Long id;
private String name;
private Map memberOfGroups;
public Long getId() { return id; }
private void setId(Long id) { this.id = id; }
public String getName() { return name; }
private void setName(String name) { this.name = name; }
// Map collection link via UserId foriegn key
// Get/Set groups of this user indexed by Group.getName()
public Map getMemberOfGroups() { return memberOfGroups; }
private void setMemberOfGroups(Map memberOfGroups) { this.memberOfGroups = memberOfGroups; }
}
class Group
{
private Long id;
private String name;
private Map groupMembers;
public Long getId() { return id; }
private void setId(Long id) { this.id = id; }
public String getName() { return name; }
private void setName(String name) { this.name = name; }
// Map collection link via GroupId foriegn key
// Get/Set groups of this user indexed by User.getName()
public Map getGroupMembers() { return groupMembers; }
private void setGroupMembers(Map groupMembers) { this.groupMembers = groupMembers; }
}