JPA - @MapKey和@EmbeddedId

时间:2015-03-21 09:47:50

标签: java hibernate jpa

我有以下数据库结构:

Main table FESTIVAL

Table with translation

FESTIVAL_ID和LANG是复合PK,FESTIVAL_ID是FKTIVAL的FK。

在我的Java代码中,我有以下实体:

@Embeddable
public class FestivalTranslationId {

    @Column(name = "FESTIVAL_ID")
    Long festivalId;

    @Column(name = "LANG")
    String lang;

    ...
}

public class FestivalTranslation {

    @EmbeddedId
    FestivalTranslationId id = new FestivalTranslationId();

    @MapsId(value = "festivalId")
    @ManyToOne
    @JoinColumn(name = "FESTIVAL_ID", referencedColumnName = "ID")
    Festival festival;

    @Column(name = "LANG")
    String lang;

    ...
}


@Entity
@Table(name = "FESTIVAL")
public class Festival {

    @OneToMany(mappedBy = "festival")
    @MapKey(name="lang")
    Map<String, FestivalTranslation> translations;

    ...
}

但是当我尝试获得节日实体时,我有例外:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'translatio0_.ID' in 'field list'

在hibernate日志中,我看到疯狂的SQL查询:

SELECT translatio0_.FESTIVAL_ID AS FESTIVAL1_14_0_,
       translatio0_.FESTIVAL_ID AS FESTIVAL1_15_0_,
       translatio0_.LANG AS LANG2_15_0_,
       translatio0_.ID AS ID3_15_0_,
       translatio0_.FESTIVAL_ID AS FESTIVAL1_15_1_,
       translatio0_.LANG AS LANG2_15_1_,
       translatio0_.ID AS ID3_15_1_
  FROM FESTIVAL_TRANSLATION translatio0_
 WHERE translatio0_.FESTIVAL_ID = ?

我的问题是,可以使用带有@EmbeddedId的实体的Map,其中key是复合PK的一部分吗?

2 个答案:

答案 0 :(得分:1)

如果您想从lang实体访问Festival属性,则无法直接执行,因为lang中没有Festival映射。您必须这样做:@MapKey(name="id.lang")因为它是通过FestivalTranslationId访问的。

here描述了一个非常类似的问题。然而,看起来可能存在一些问题,lang映射存在于映射的键和值中(它取决于您正在使用的实际JPA提供程序 - 它在Hibernate中存在问题)。

答案 1 :(得分:0)

示例方法可能如下所示:

@Embeddable
public class FestivalId implements Serializable {
    @Column(name = "FESTIVAL_ID")
    private int id;
    ...
}
@Embeddable
public class FestivalTranslationId implements Serializable {
    @Embedded
    private FestivalId festivalId;

    @Column(name = "LANG")
    private String lang;
    ...
}
@Entity
@Table(name = "FESTIVAL")
public class Festival {
    @EmbeddedId
    @AttributeOverride(name = "id", column = @Column(name = "ID"))
    private FestivalId festivalId;

    @MapsId(value = "festivalId")
    @OneToMany(mappedBy = "festival")
    @MapKey(name = "festivalTranslationId")
    private Map<String, FestivalTranslation> translations;
    ...
}
@Entity
@Table(name = "FESTIVAL_TRANSLATION")
public class FestivalTranslation {
    @EmbeddedId
    private FestivalTranslationId festivalTranslationId;

    @ManyToOne
    private Festival festival;
    ...
}

以上实体产生以下表格:

FESTIVAL            FESTIVAL_TRANSLATION
--------            --------------------
ID    PK            FESTIVAL_ID    FK PK
                    LANG              PK

使用Hibernate 4.3.8.Final

进行测试