I am trying to design an entity class with the "Encapsulate Collection" refactoring, using Collections.unmodifiableSet().
http://www.refactoring.com/catalog/enca ... ction.html
However, I have been encountering all sorts of difficulty with this approach, as Hibernate is throwing NullPointerExceptions at various places. I understand that Hibernate uses its own Collections implementations (PersistentSet, etc.), but I am not exactly sure how this should impact my code.
Rather troubleshooting the specific errors I am seeing, I would like to back up a bit and make sure I am taking the recommended approach in my class design.
The entity in question has a 1-to-many bi-directional association (i.e. Parent-Children). Based on the errors I have encountered, it seems that Hibernate requires something like the following:
Code:
public class Parent {
Set children = new HashSet();
// protected setter for Hibernate
protected void setChildren(Set children) {
this.children = children;
}
public Set getChildren() {
return children;
// this implementation would cause errors
// return Collections.unmodifiableSet(children);
}
// "work around" method - not a mapped property
public Set getAllChildren() {
return Collections.unmodifiableSet(children);
}
// another solution I've seen - defensive copy
public Iterator getChildrenIterator() {
List temp = new ArrayList(children);
return temp.iterator();
}
}
What is the a recommended Best Practice for encapsulating collections with Hibernate?
Related question:
What is the recommended way to ensure that the collections are always initialized? The Hibernate reference seems to advocate explicitly assigning a new collection instance to the field via the property setter (23.3. Hibernate Code - BlogMain.createBlog), but that feels wrong somehow. Why not initialize the the collection in the constructor, field declaration, or lazily in the method? My question is: what pitfalls await me if I take one of these three approaches?