开发者

Howto Persist a Map<Entity, Integer> with JPA?

开发者 https://www.devze.com 2023-04-09 02:48 出处:网络
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 Progres

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号