簡體   English   中英

具有接口屬性的 JPA 實體,可能嗎?

[英]JPA entity with a interface attribute, is it possible?

我有以下實體:

@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 以在運行時執行中設置正確的類 ID?

其他資源:

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 個類之一的 id?

提前致謝,

這確實是一個好主意,但不幸的是,JPA 不支持將接口直接映射為實體屬性。

您只能映射直接用@Entity注釋的頂級類。 不過,這個頂級類可能會實現一個接口。

此功能已被請求和討論了很長時間。

也看看這個這個

根據您要完成的任務,帶有 table-per-class 策略的@Inheritance注釋可能是一種選擇。

我希望它有幫助。

不,不能使用 JPA 或 Hibernate。

看起來很奇怪,當使用允許屬性作為接口的 Java 語言進行編碼時,像 JPA 這樣的用於 Java 的持久性標准不支持作為接口的持久性屬性。

當我的 ORM 強迫我重構我的“純”OO 模型使其能夠持久化時,我總是發現它真的非常令人沮喪。

並不是說實現接口屬性的持久化在技術上是不可能的——事實上,JDO 一直支持接口的持久化,這就是為什么我多年前開始在我自己的所有項目中使用它。

我一直想改用 JPA,不是因為它在技術上更勝一籌(事實上,恰恰相反),而只是因為“從眾心態”。

在最近的合同工作中,我被迫獲得了 JPA/Hibernate 的經驗,在這樣做的過程中,與 JDO/DataNucleus 相比,我已經體驗到了這種組合的許多局限性和低效率。 這是一次很棒的經歷,因為它幫助我平息了加入“羊群”的願望:)

有一個警告是可能的 - 您必須將 JPA 指向一個應該是具體類的目標實體。 但是,它可以是實現您的接口的抽象類。 因此,您必須打破良好設計的一項原則,特別是“優先組合而不是繼承”。

這是如何做到的:

  1. 在您的用戶類(引用您的接口Task )中:
    @OneToOne(targetEntity = BaseTask.class)
    private Task task;

所以這里Task是一個接口,但你必須聲明一個抽象類BaseTask

  1. 在您的BaseTask
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="task_type")
@Table(name="Task")
public abstract class BaseTask implements Task{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    }

這里重要的是@DiscriminatorColumn - 因為繼承樹的所有字段都將存儲在 1 個表中(您使用上面的@Inheritance(strategy = InheritanceType.SINGLE_TABLE)注釋指定。所以這個鑒別器列將包含一個標簽,允許JPA 來區分您所談論的任務類型

  1. 您的具體課程:
@Entity
@DiscriminatorValue("api")
public class ApiTask extends BaseTask {

要么

@Entity
@DiscriminatorValue("ssh")
public class SshTask extends BaseTask{

如您所見,鑒別器值告訴 JPA 它將加載什么任務(要實例化的類)。

您需要使用您喜歡的任何策略( 請參閱文檔)在 JPA 中正確設置 ScriptItem 的繼承,然后 JPA 會很聰明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM