JPA-объект с атрибутом интерфейса, возможно ли это?

У меня есть следующая сущность:

@Entity
public class TestCaseStep implements JPAEntity<Integer> {

        ...

    @Column(name="STEP_NUMBER")
    private Integer stepNumber;

    @Enumerated(EnumType.STRING)
    @Column(name="ACTION")
    private Action action;

    **@ManyToOne
    @JoinColumn(name="connector")
    private ScriptItem connector;**

Мой атрибут ScriptItem - это интерфейс для 3 других классов. Можно ли настроить JPA для установки правильного идентификатора класса во время выполнения?

Другие источники:

public interface ScriptItem {

    String getValue();
    ScriptItemType getType();
}

@Entity
@Table(name="DAT_FEED_XML")
public class FeedXml implements JPAEntity<Integer>, ScriptItem {
    ...
}

@Entity
@Table(name="DAT_DB_STMT")
public class DbStatement implements JPAEntity<Integer>, ScriptItem {
       ...
}

Какие аннотации мне следует использовать, чтобы JPA поняла, что я хочу сохранить идентификатор одного из 3 классов?

Заранее спасибо,

Ответ 1

Это действительно хорошая идея, но, к сожалению, прямое отображение интерфейсов как атрибута сущности не поддерживается JPA.

Вы можете отображать только классы верхнего уровня, напрямую аннотированные @Entity. Этот класс верхнего уровня может реализовать интерфейс.

Эта функция была запрошена и обсуждалась в течение длительного времени.

Также взгляните на это и это.

В зависимости от того, что вы пытаетесь достичь, аннотация @Inheritance со стратегией таблица-на-класс может быть вариантом.

Я надеюсь, что это помогает.

Ответ 2

Нет, невозможно с JPA или Hibernate.

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

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

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

У меня возникло соблазн переключиться на JPA не потому, что это технически превосходно (на самом деле, совсем наоборот), а только из-за "стадного менталитета".

В недавней контрактной работе я был вынужден получить опыт работы с JPA/Hibernate, и при этом выдержал множество ограничений и неэффективности этой комбинации по сравнению с JDO/DataNucleus. Это был отличный опыт, потому что это помогло мне подавить мое желание присоединиться к "стаду":)

Ответ 3

Вам необходимо правильно настроить наследование ScriptItem в JPA, используя любую стратегию, которую вы предпочитаете (см. документы), а затем JPA будет умным он.