如何使用JPA </entity>继承Map <entity,integer =“”>

时间:2011-09-28 04:14:59

标签: java hibernate jpa jpa-2.0

我正在努力迁移一些具有两个实体(Progress和PerformanceRating)的代码,这些实体与多对多关系相关。每个PerformanceRating都有多个Progress,每个Progress类型可以分配给多个PerformanceRating。此外,每个PerformanceRating-&gt; Progress都有一个与进度相关的额外“金额”值。

当前PerformanceRating对象包含一个Map,表示分配给PerformanceRating对象的每个Progress类型的“进度”。

编码如下:

@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;
}

然而,当我启动JBoss(使用hibernate 3.6 / JTA / JPA)时,我收到以下错误:

Use of @OneToMany or @ManyToMany targeting an unmapped class: fwl.domain.model.PerformanceRating.rewardAmountByProgressMap[java.lang.Integer]

我找到了一个类似的线程(Persist a Map<Integer,Float> with JPA),但那个似乎处理非实体类型。在像我这样的情况下,我正在寻找实体/值类型映射,正确的语法是什么?

有没有办法在Hibernate / JPA2中执行此操作?

谢谢,

埃里克

1 个答案:

答案 0 :(得分:1)

你得到的错误:

  

使用@OneToMany或@ManyToMany 定位未映射的类:fwl.domain.model.PerformanceRating.rewardAmountByProgressMap [ java.lang.Integer ]

与使用@OneToMany@ManyToMany这样的注释相关的事实表明,声明类(PerformanceRating)与地图的处于多对多关系中值Integer 傻>

你的地图的价值应该是一个实体,它的关键字应该是你可以用来识别你映射的那些实体之一的id(实际上关键必须是唯一的,我认为,它不需要是一个真实的身份。)


我真的不知道你的桌子是怎么样的,但如果你的PerformanceRating(为了方便起见,我们只称它为Rating)看起来像这样:

rating
============
id               int(11) PK

和您的Progress表格如下:

progress
============
id               int(11) PK
amount           int(11)

用表连接这些:

progress_has_rating
============
progress_id      int(11) PK
rating_id        int(11) PK

然后您可以通过以下方式映射这些:

@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;
}

(很有可能我在实际工作的@JoinColumn注释中切换了列名;我总是切换它们。)

(编辑:是的,我已将它们改为固定。)


如果你的amount属性在你的连接表中,那么你还需要为它创建一个实体类。我认为不可能绕过

如果你真的想使用地图,那么Hibernate可以管理它。请参阅Collection mapping部分(特别是第7.2.2.2节),了解如何映射地图。不过,地图中的值需要是某种实体。