У меня есть следующая структура БД:
Где FESTIVAL_ID и LANG являются составными PK, а FESTIVAL_ID - FK для FESTIVAL.
В моем 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'
В журналах спящего режима я вижу безумный 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 = ?
Мой вопрос, можно использовать Map для объектов с @EmbeddedId, где ключ является частью составного PK?
Примерный подход может выглядеть следующим образом:
@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
Протестировано с гибернацией 4.3.8.
Если вы хотите получить доступ к собственности lang
из объекта Festival
вы не можете сделать это напрямую, потому что в Festival
нет отображения lang
. Вы должны сделать это следующим образом: @MapKey(name="id.lang")
поскольку он доступен через FestivalTranslationId
.
Существует очень похожая проблема, описанная здесь. Однако похоже, что могут возникнуть некоторые проблемы с тем, что отображение lang
присутствует как в ключе, так и в значении карты (это зависит от фактического поставщика JPA, который вы используете - в Hibernate есть проблемы).
FestivalTranslation
сID
field = (