I think this is pretty much the simplest case for mapping a Map (that is, an associative array) of entities.
@Entity
@AccessType("field")
class Member {
@Id
protected long id;
@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY)
@MapKey(name = "name")
private Map<String, Preferences> preferences
= new HashMap<String, Preferences>();
}
@Entity
@AccessType("field")
class Preferences {
@ManyToOne Member member;
@Column String name;
@Column String value;
}
This looks like开发者_Go百科 it should work, and it does, in HSQL. In MySQL, there are two problems: First, it insists that there be a table called Members_Preferences, as if this were a many-to-many relationship.
Second, it just doesn't work: since it never populates Members_Preferences, it never retrieves the Preferences.
[My theory is, since I only use HSQL in memory-mode, it automatically creates Members_Preferences and never really has to retrieve the preferences map. In any case, either Hibernate has a huge bug in it or I'm doing something wrong.]
And of course, I sweat the problem for hours, post it here, and a minute later...
Anyway, the answer is the mappedBy element of the @OneToMany annotation:
@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="member")
@MapKey(name = "name")
private Map<String, Preferences> preferences
= new HashMap<String, Preferences>();
Which makes a certain sense: which field in the Many entity points back to the One entity? Even allowing that looking for a matching @ManyToOne field was too error prone, I think that what they did do (assuming the existence of a mapping table) makes even worse.
精彩评论