Howto Persist a Map<Entity, Integer> with JPA?
I'm working on migrating some code that has two entities (Progress and PerformanceRating) that are related by a many-to-many relationship. Each PerformanceRating has multiple Progress and each Progress type can be assigned to several PerformanceRatings. Additionally, each PerformanceRating->Progress has an additional "amount" value that relates to开发者_JS百科 the progress.
Current the PerformanceRating object contains a Map representing the "amount" of progress for each Progress type assigned to the PerformanceRating object.
It is coded as follows:
@Entity
class PerformanceRating{
....
....
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "performance_rating_progress_reward", joinColumns = { @JoinColumn(name = "id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "amount", nullable = false, updatable = false) })
public Map<Progress, Integer> getRewardAmountByProgressMap() {
return this.rewardAmountByProgressMap;
}
However, when I start JBoss (with hibernate 3.6/JTA/JPA), I get the following error:
Use of @OneToMany or @ManyToMany targeting an unmapped class: fwl.domain.model.PerformanceRating.rewardAmountByProgressMap[java.lang.Integer]
I found a similar thread (Persist a Map<Integer,Float> with JPA), but that one seems to deal with non-entity types. In a case such as mine, where I am looking for an Entity/value type mapping, what is the correct syntax?
Is there a way to do this in Hibernate/JPA2?
Thanks,
Eric
The error you get:
Use of @OneToMany or @ManyToMany targeting an unmapped class: fwl.domain.model.PerformanceRating.rewardAmountByProgressMap[java.lang.Integer]
relates to the fact that with annotations like @OneToMany
and @ManyToMany
you say that the declaring class (PerformanceRating
) is in a many-to-many relation with your map's value, Integer
which is silly.
The value of your map should be an entity, its key should be the id with which you can identify one of those entities that your map contains (actually the key have to be only unique, I think, it needn't be an actual id).
I really don't know how your table looks like, but if your PerformanceRating
(lets call it just Rating
for ease's sake) looks like this:
rating
============
id int(11) PK
and your Progress
table like this:
progress
============
id int(11) PK
amount int(11)
with a table connecting these like this:
progress_has_rating
============
progress_id int(11) PK
rating_id int(11) PK
then you can map these in the following way:
@Entity @Table class Rating {
@Id long id;
@ManyToMany(targetEntity = Progress.class,
cascade = CascadeType.ALL,
fetch = FetchType.EAGER)
@JoinTable(name = "progress_has_rating",
joinColumns = {@JoinColumn(name = "rating_id",
referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "progress_id",
referencedColumnName = "id")})
Set<Progress> progresses;
}
@Entity class Progress {
@Id long id;
@Basic long amount;
}
(It's quite possible that I switched up the column names in the @JoinColumn
annotations that would actually work; I always switch 'em up.)
(Edit: yes, I've switched them—fixed.)
If your amount
property is in your join table, then you'll need to create an entity class for that also. I think it isn't possible to get around that.
If you really want to use maps, then Hibernate can manage that. See the Collection mapping section (section 7.2.2.2 particularly) on how to map maps. Still, values in your map would need to be entities of some kind.
精彩评论