我正在迁移一些具有通过多对多关系关联的两个实体(Progress和PerformanceRating)的代码。每个PerformanceRating具有多个Progress,并且每个Progress类型可以分配给几个PerformanceRatings。此外,每个PerformanceRating-> Progress具有与进度相关的附加“金额”值。

当前,PerformanceRating对象包含一个Map,该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(使用休眠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中有没有办法做到这一点?

谢谢,

埃里克

最佳答案

您得到的错误:

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

与以下事实有关:使用@OneToMany@ManyToMany这样的注释,您说声明类(PerformanceRating)与地图的值Integer是多对多的关系,这很愚蠢。

地图的值应该是一个实体,其键应该是可以用来标识地图包含的那些实体之一的ID(实际上,键只能是唯一的,我想,它不必是实际的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节)。尽管如此,地图中的值仍需要是某种类型的实体。

09-05 21:42