When mapping a ternary association with a Map, Map.Entry value cannot be null. Why is that, and can it be changed ?
Say we have a ternary association mapped with a java.util.Map as described in 'Java Persistence With Hibernate' (looking from a perspective of a Category):
Code:
@ManyToMany
@org.hibernate.annotations.MapKeyManyToMany(
joinColumns = @JoinColumn(name = "ITEM_ID")
)
@JoinTable(
name = "CATEGORY_ITEM",
joinColumns = @JoinColumn(name = "CATEGORY_ID"),
inverseJoinColumns = @JoinColumn(name = "USER_ID")
)
private Map<Item,User> itemsAndUser = new HashMap<Item,User>();
If we wanted to persist a map entry with a null User, that would not be possible.
I tracked down the source of this to this method in
PersistentMap class:
Code:
@Override
@SuppressWarnings("unchecked")
public boolean entryExists(Object entry, int i) {
return ( (Map.Entry) entry ).getValue() != null;
}
which apparently checks if the map entry value is null, and if it is, Hibernate does not persist the entry.
Now I guess this can be circumvented implementing a custom UserCollectionType that would wrap the map in a PersistentMap subclass that would remove the checking.
However I am interested in the logic of this - why can't the PersistentMap let a null-value Map.Entry be persisted ?
Thanks a lot in advance
IvanM
==========EDIT===========
I think I found another way to circumvent this obstacle.
I created a helper @Embeddable class for holding the User value , let's call it UserEmbeddable:
Code:
@Embeddable
public class UserEmbeddable
{
@ManyToOne
private User User;
... setters & getters...
}
Now in Category the map looks like this:
Code:
@ElementCollection
@MapKeyJoinColumn(
name="ITEM_ID", nullable=false
)
@CollectionTable(
name = "CATEGORY_ITEM",
joinColumns = @JoinColumn(name = "CATEGORY_ID")
)
private Map<Item,UserEmbeddable> itemsAndUser = new HashMap<Item,UserEmbeddable>();
Hibernate generates a table like this:
Code:
create table CATEGORY_ITEM (
CATEGORY_ID varchar(36) not null,
USER_ID varchar(36),
ITEM_ID varchar(36) not null,
primary key (CATEGORY_ID, ITEM_ID)
)
and successfully inserts the row into this join table.