Разрешает ли спецификация JPA ссылки на столбцы без первичного ключа?
Разрешает ли спецификация JPA простые ссылки на столбцы без первичного ключа?
У меня есть простой столбец альтернативного / естественного ключа (UNIQUE, NOT NULL) iso_code в моей таблице стран, который я хотел бы использовать в качестве ссылки, но Dali в Eclipse показывает ошибку проверки, а Hibernate генерирует исключение MappingException.
Разрешен ли такой общий сценарий?
2 ответа
@axtavt: Похоже, что ваш ответ не был правильным. Я только что получил письмо от авторов "Pro JPA 2.0", которые также сами работали над спецификацией JPA.
"В вашем примере класс Zip имеет отношение к стране:
public class Zip implements Serializable
{
@Id
@Column(name = "code")
private String code;
@Id
@ManyToOne
@JoinColumn(name = "country_code", referencedColumnName = "iso_code")
private Country country = null;
...
}
Похоже, что он пытается указать столбец внешнего ключа country_code на столбец iso_code в таблице Country, который не является PK. JPA никогда не позволяла вам создавать подобные отношения, потому что без указания PK страны не было бы способа однозначно определить, какой экземпляр Country находится в отношениях. Вы просто сталкиваетесь с проблемой, когда добираетесь до производной части идентификатора, но проблема, похоже, заключается в самих недопустимых отношениях ".
Таким образом, спецификация JPA вообще не разрешает отношения /FK для не-PK столбцов...
Поддержка отношений, которые ссылаются на столбцы не-PK, является необязательной функцией. В простых случаях он поддерживается Hibernate, но его нельзя использовать как часть идентификатора с использованием dervied.
Однако до тех пор, пока вы не получите идентификатор (т. Е. Если вы можете установить значение компонента первичного ключа вручную), вы можете попытаться поиграть с отображениями только для чтения, что-то вроде этого:
@Entity
@Table(name = "Zips")
@IdClass(value = ZipId.class)
public class Zip implements Serializable
{
@Id
@Column(name = "code")
private String code;
@Id
@Column(name = "country_code")
private String countryCode; // Primary key component should be set manually
@ManyToOne
@JoinColumn(name = "country_code", referencedColumnName = "iso_code",
insertable = false, updateable = false)
private Country country = null; // Read-only relationship based on a value
// of primary key component
...
}