On my entity (myGroup : Group
) I have a collection property (members : HashMap<Long, GroupMember>
) and I want to allow the user to add multiple new (unpersisted) GroupMember
s to the myGroup.members
map.
The reason why I am using a hashmap for the collection property is to ensure the use of the collection is performant (i.e. must be able to get a
GroupMember
by its ID quickly and multiple times during execution of the business logic).The reason why I don't want to persist them straight away is to support reversion of the additions. The user must be able to manipulate the
myGroup.members
map, adding and removing members until satisfied, before persisting (saving the entities in the Hibernate session and flushing).
The problem is that new GroupMember
s must be assigned an ID of zero for Hibernate to detect that they're unsaved.(*) Because the members are in a map, keyed by ID, that means only one new member can be added prior to either a save or revert. The addition of a second new member with ID zero simply overrides (the reference to) the first.
My question is how can I best adapt my code solution to support the addition of multiple unsaved entities to the collection (myGroup.members
) while keeping the performance advantage of using a hashmap or other map/dictionary?
Note: I have already tried a hack whereby a ID is derived from unique combination of data in a GroupMember
instance and then, just before a save, the ID is set to zero in order for Hibernate to detect it needs to be persisted, but it is inelegant and I haven't found a way for it to work reliably.
* I don't fully understand Hibernate's behaviour in this regard.
Abbreviated code for the Group
entity below:
@Entity
@Table (name="GROUP")
public class Group
{
private Map<Long,GroupMember> members = new HashMap<Long,GroupMember>();
@OneToMany(fetch = FetchType.LAZY, mappedBy = "ownerGroup", cascade = { CascadeType.ALL })
@MapKey(name="id")
public Map<Long,GroupMember> getMembers() { return this.members; }
public void setMembers(Map<Long,GroupMember> members) { this.members = members; }
// ...other properties and methods...
}