Как сделать сопоставленное поле унаследованным от переходного процесса суперкласса в JPA? - PullRequest
10 голосов
/ 07 мая 2009

У меня есть устаревшая схема, которую нельзя изменить. Я использую базовый класс для общих функций, и он содержит встроенный объект. Существует поле, которое обычно отображается во встроенном объекте и должно быть в постоянном идентификаторе только для одного (из многих) подклассов. Я сделал новый класс id, который включает его, но затем я получаю ошибку, что поле отображается дважды. Вот пример кода, который значительно упрощен для поддержания здравомыслия читателя:

@MappedSuperclass
class BaseClass {
    @Embedded
    private Data data;
}

@Entity
class SubClass extends BaseClass {
    @EmbeddedId
    private SubClassId id;
}

@Embeddable
class Data {
    private int location;

    private String name;
}

@Embeddable
class SubClassId {
    private int thingy;

    private int location;
}

Я попытался @AttributeOverride, но я могу только заставить его переименовать поле. Я попытался установить для него значение updatable = false, вставка = false, но это не помогло при использовании в аннотации @AttributeOverride. См. Ответ ниже для решения этой проблемы.

Я понимаю, что могу изменить базовый класс, но я действительно не хочу разделять встроенный объект, чтобы отделить общее поле, так как это сделает окружающий код более сложным и потребует некоторого уродливого кода для переноса. Я мог бы также перепроектировать всю систему для этого углового случая, но я действительно не хотел бы.

Я использую Hibernate в качестве поставщика JPA.

1 Ответ

5 голосов
/ 07 мая 2009

Я нашел причину, по которой AttributeOverride не работал. При аннотировании класса вы должны включить идентификатор встроенного объекта в поле имени. Я делал это:

@Entity
@AttributeOverride(name = "location", column = @Column(name = "location", insertable = false, updatable = false)
class SubClass extends BaseClass {

Когда это должно было быть:

@Entity
@AttributeOverride(name = "data.location", column = @Column(name = "location", insertable = false, updatable = false)
class SubClass extends BaseClass {

Странно то, что изменение поля имени @ Column сработало с первой версией, но вставляемые и обновляемые поля были проигнорированы. Я не знаю, является ли это ошибкой или тонкостью спецификации JPA.

В любом случае, это решает, как сделать поле доступным только для чтения, но не отвечает на первоначальный вопрос: возможно ли сделать поле из отображенного переходного суперкласса?

...