Подтвердить что ты не робот

Указывает ли спецификация JPA ссылки на столбцы не первичного ключа?

Является ли спецификация JPA простой ссылкой на столбцы непервичного ключа?

У меня есть простой альтернативный/естественный ключ (UNIQUE, NOT NULL) column iso_code в таблице моих стран, который я бы хотел использовать в ссылке, но Eclipse Dali показывает ошибку проверки, а Hibernate генерирует исключение MappingException.

Разрешен ли такой общий сценарий?

4b9b3361

Ответ 1

@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 страны не было бы возможности однозначно идентифицировать, какой экземпляр страны находится в отношениях. Вы просто сталкиваетесь с проблемой, когда попадаете в производную часть идентификатора, но проблема, похоже, связана с недействительными отношениями. "

Таким образом, спецификация JPA не позволяет отношениям /FKs не столбцам PK вообще...

Ответ 2

Поддержка отношений, которые ссылаются на столбцы, отличные от PK, является необязательной функцией. В простых случаях он поддерживается Hibernate, но он не может использоваться как часть скрытой идентичности.

Однако, пока вы не получаете идентификатор (т.е. если вы можете установить значение первичного ключевого компонента вручную), вы можете попытаться сыграть с отображениями только для чтения, примерно так:

@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

    ...
}