休眠:将非主键的一对多引用映射到主键

时间:2019-06-21 12:23:47

标签: hibernate hibernate-mapping

我有一个旧式数据库,在该数据库中很少(很少)放置外键。如果我在java中创建自己的外键(B.nummer上的列A.testnr点),hibernate将使用A的主键(列ID),这将导致(按预期)错误。

我已经读到我必须在B类的列上放置一个mappingBy-Reference。B类中的主键是一个数字,我试图将其更改为Set(A),但是随后我遇到了一些持久性错误。

映射ManyToOne关系-A.testnr-> B.nummer

Class A    

@Id
@Column(name = "NUMMER", unique = true, nullable = false, precision = 22, 
scale = 0)
public BigDecimal getNummer() {
 return this.nummer;
}

public void setNummer(BigDecimal nummer) {
  this.nummer = nummer;
 }

@ManyToOne
@JoinColumn(name = "nummer", referencedColumnName = "nummer")
public B getTestnr() {
  return this.testnr;
}

public void setTestnr(B testnr) {
  this.testnr = testnr;
}


Class B

@Id
@Column(name = "NUMMER", unique = true, nullable = false, precision = 22, 
  scale = 0) 
public BigDecimal getNummer() {
  return this.nummer;
}

public void setNummer(BigDecimal nummer) {
  this.nummer = nummer;
}

错误消息:javax.persistence.EntityNotFoundException导致A(A.nummer)中的主键不属于B.nummer。

正如我已经告诉我的,我尝试使用MappedBy-Reference并将B类中的BigDecimal PK更改为Set(A)。

@Id
@OneToMany(fetch = FetchType.EAGER, mappedBy = "testnr")
@Column(name = "NUMMER", unique = true, nullable = false, precision = 22, 
 scale = 0)
public Set<A> getNummern() {
  return this.nummern;
}

public void setNummern(Set<A> nummern) {
  this.nummern = nummern;
}

通过此更改,可能会由于持久层中的差异而导致运行时错误。

我的目标是,即使在休眠状态下也可以将非主键映射到另一个类的主键,还是我被迫使用本机sql的情况?

1 个答案:

答案 0 :(得分:1)

  

为了对未索引的列进行联接,这是绝对正确的,您必须使用referencedColumnName。但是,在第二个代码片段中,您将@ManyToOne集合标记为id,这是不正确的。如果我对您的理解正确,则多个A.nummer属于一个B.testnr。

这就是您想要的方式:

  

A类,属于testnr的数字。

@Entity
@Table(name = "a_table")
public class A {

    @Id // a_table_id
    @Column(name = "NUMMER", unique = true, nullable = false, precision = 22)
    private BigDecimal nummer;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "nummer", referencedColumnName = "nummer")
    // make sure referenced column name matches column in table B
    private B testnr;

    public BigDecimal getNummer() {
        return this.nummer;
    }

    public void setNummer(BigDecimal nummer) {
        this.nummer = nummer;
    }

    public B getTestnr() {
        return this.testnr;
    }

    public void setTestnr(B testnr) {
        this.testnr = testnr;
    }

}
  

B类,具有多个数字的testnr。

@Entity
@Table(name = "b_table")
public class B {

    @Id // b_table_id
    @Column(name = "b_table_id")
    private BigDecimal testnr;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "testnr")
    private Set<A> nummern;

    public Set<A> getNummern() {
        return this.nummern;
    }

    public void setNummern(Set<A> nummern) {
        this.nummern = nummern;
    }
}