Как сделать сопоставленное поле, унаследованное от переходного суперкласса в JPA?

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

@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, но смог заставить его только переименовать поле. Я попытался установить для него значение updateable = false, insertable = false, но это не сработало при использовании в аннотации @AttributeOverride. См. ответ ниже для решения этой проблемы.

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

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


person Russ Hayward    schedule 07.05.2009    source источник


Ответы (1)


Я нашел причину, по которой 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.

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

person Russ Hayward    schedule 07.05.2009
comment
Я знаю, что этому уже 6 лет, но вы когда-нибудь находили решение этого вопроса? И/или помните, что это было? - person Eric B.; 30.09.2015
comment
@ЭрикБ. Извините, так и не нашел способ не наследовать сопоставленное поле. Я не думаю, что это возможно сделать. Я думаю, что они могут воспринять это как попытку уменьшить видимость унаследованного метода в Java - так что это просто против правил. В моем случае я работал за углом, что немного уродливо, но было единственным вариантом. - person Russ Hayward; 01.10.2015