Hibernate:将一对多引用从非主键映射到主键
Hibernate: Mapping a One-To-Many-Reference from a non primary key to a primary key
我有一个遗留数据库,其中(不幸的是)很少放置外键。如果我在 java 中创建自己的外键(列 A.testnr 指向 B.nummer),hibernate 正在使用 A 的主键(列 id),这会(如预期)导致错误。
我读到我必须在 class B 的列上放置一个 mappedBy-Reference。 class B 中的主键是一个数字,我试图将它更改为一个 Set( A)但是我得到了一些持久性错误。
映射多对一关系 - 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 并将 class 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;
}
通过此更改,我收到运行时错误可能是由于持久层中的差异。
我的目标是将一个非主键映射到另一个 class 的主键甚至可以使用休眠,还是在这种情况下我被迫使用本机 sql?
In order for you to make a join on a non-indexed column, that's absolutely right, you have to use referencedColumnName
. However in your second code snipped you marked your @ManyToOne
collection as id, which is incorrect. If I understood you correctly, multiple A.nummer belong to a single B.testnr.
这就是您得到想要的东西的方式:
Class A, nummer which belongs to 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;
}
}
Class B, testnr that has multiple nummers.
@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;
}
}
我有一个遗留数据库,其中(不幸的是)很少放置外键。如果我在 java 中创建自己的外键(列 A.testnr 指向 B.nummer),hibernate 正在使用 A 的主键(列 id),这会(如预期)导致错误。
我读到我必须在 class B 的列上放置一个 mappedBy-Reference。 class B 中的主键是一个数字,我试图将它更改为一个 Set( A)但是我得到了一些持久性错误。
映射多对一关系 - 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 并将 class 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;
}
通过此更改,我收到运行时错误可能是由于持久层中的差异。
我的目标是将一个非主键映射到另一个 class 的主键甚至可以使用休眠,还是在这种情况下我被迫使用本机 sql?
In order for you to make a join on a non-indexed column, that's absolutely right, you have to use
referencedColumnName
. However in your second code snipped you marked your@ManyToOne
collection as id, which is incorrect. If I understood you correctly, multiple A.nummer belong to a single B.testnr.
这就是您得到想要的东西的方式:
Class A, nummer which belongs to 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;
}
}
Class B, testnr that has multiple nummers.
@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;
}
}