繁体   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