簡體   English   中英

JPA從多對一關系中獲取價值

[英]JPA fetching value from Many to One relationship

我在將多對一關系中的單個值嵌入JPA中時遇到問題。 下面有一些代碼用於初始化測試模式以及測試實體。

這個想法是,有一個表EMPLOYEE引用了表RANK。 表RANK依次包含RANK的名稱。 每個員工都參照其職級。

當我嘗試運行代碼時,出現以下異常:

Caused by: org.hibernate.AnnotationException: SecondaryTable JoinColumn cannot reference a non primary key
    at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:623)
    at org.hibernate.cfg.annotations.EntityBinder.bindJoinToPersistentClass(EntityBinder.java:764)
    at org.hibernate.cfg.annotations.EntityBinder.createPrimaryColumnsToSecondaryTable(EntityBinder.java:756)
    at org.hibernate.cfg.annotations.EntityBinder.finalSecondaryTableBinding(EntityBinder.java:684)
    at org.hibernate.cfg.SecondaryTableSecondPass.doSecondPass(SecondaryTableSecondPass.java:29)

這是一個數據庫模式

CREATE TABLE RANK (
    ID INT NOT NULL, 
    NAME VARCHAR
);
ALTER TABLE RANK ADD PRIMARY KEY (ID);
INSERT INTO RANK (ID, NAME) VALUES (1, 'WORKER')

CREATE TABLE EMPLOYEE(
    ID INT NOT NULL, 
    NAME VARCHAR,
    RANK_ID INT NOT NULL
);
ALTER TABLE EMPLOYEE ADD PRIMARY KEY (ID);
INSERT INTO EMPLOYEE (ID, NAME, RANK_ID) VALUES (1, 'Bobby', 1);

最后,唯一的實體:

@Entity
@Table(name = "EMPLOYEE")
@SecondaryTable(name = "RANK", pkJoinColumns=@PrimaryKeyJoinColumn(name="ID", referencedColumnName = "RANK_ID"))
public class Employee {

    @Id
    @Column(name = "id")
    @GeneratedValue(generator = "increment")
    @GenericGenerator(name = "increment", strategy = "increment")
    private int id;

    @Column(name = "NAME")
    private String name;

    @Column(name = "RANK_ID")
    private int rankId;

    @Column(name = "name", table = "RANK")
    private String rank;

    public Employee() {

    }
}

對於如何解決此問題的任何提示,我將不勝感激。 假定使用JPA無法做到這一點很普遍。

使用輔助表批注時,請引用Employee ID並刪除rank_id 您說的是通過使用該注釋將數據分布在多個表中,因此基本上兩者的主鍵是相同的。 實際上,由於兩個PK具有相同的標識符,因此甚至不必定義@PrimaryKeyJoinColumn

請參考這里: https : //docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/SecondaryTable.html

在另一方面,如果你只是想許多人,你可以使用一個關系@ManyToOne注釋和@JoinColumnrank_id

如果您閱讀Java Persistence Wikibook的這一部分,將會看到JPA規范未涵蓋您想要的內容,因此底層提供程序可能不支持您想要的內容:

JPA規范並未直接涵蓋這一點,因此,如果您具有這種情況,那么,如果您有靈活性,首先要考慮的是更改數據模型,使其不超出規范的范圍。

@SecondaryTable主要用於將一對一表鏈接到一個實體。

實現所需目標的“標准”方法是為Rank創建一個單獨的實體,而EAGER在Employee獲取它。 然后,您可以在Employee有一個名為getRankName()的方法,該方法返回this.rank.getName() 因此,您的Employee類如下所示:

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    @Column(name = "id")
    @GeneratedValue(generator = "increment")
    @GenericGenerator(name = "increment", strategy = "increment")
    private int id;

    @Column(name = "NAME")
    private String name;

    @ManyToOne(fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name = "RANK_ID", referencedColumnName = "ID")
    private Rank rank;

    public Employee() {

    }

    public String getRankName() {
        if (this.rank == null) {
            return null;
        }
        return this.rank.getName();
    }
}

暫無
暫無

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

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