我的數據庫中有兩個表通過複合主鍵/外鍵映射到一起,我有一段時間讓Hibernate與它們一起工作。我的數據庫看起來是這樣的:休眠OneToMany與不匹配的複合主鍵
TABLE1有外鍵的複合主鍵,映射TABLE_A和表-B。 TABLE2還具有外鍵的組合主鍵,映射到TABLE_A,TABLE_B和TABLE_D。在數據庫中,TABLE2僅使用前兩個外鍵映射回TABLE1。那裏沒有問題。它將這個轉化成了Hibernate,它正在殺死我。
因爲TABLE2需要帶有三列的嵌入ID,所以我不能使用@OneToMany註解的mappedBy參數。我得到的外鍵數量與主鍵列不匹配的預期錯誤。所以我改用@JoinColumns。這對保存新實體非常合適。但是,當我試圖從TABLE2中刪除一些映射時,我遇到了一個問題,在刪除前Hibernate試圖更新TABLE2,將FK_TABLE_A設置爲null,這顯然是不允許的。我已經能夠找到的最好的方法是在映射xml中使用inverse =「true」可以解決問題,確保Hibernate知道盡管使用了@JoinColumn,TABLE1實體應該是關係的所有者。但是我沒有使用XML,而且我也無法弄清楚通過註釋可能是什麼。
這是我到目前爲止有:
@Entity
@AssociationOverrides({
@AssociationOverride(name = "pk.tableA",
joinColumns = @JoinColumn(name = "FK_TABLE_A")),
@AssociationOverride(name = "pk.tableB",
joinColumns = @JoinColumn(name = "FK_TABLE_B")) })
@Table(name="TABLE1")
public class Table1 extends BaseObject implements Serializable
{
private static final long serialVersionUID = 1L;
private Table1Id pk = new Table1Id();
@EmbeddedId
public Table1Id getPk() {
return pk;
}
public void setPk(Table1Id pk) {
this.pk = pk;
}
private TableC tableC;
@ManyToOne
@JoinColumn(name = "FK_TABLE_C", referencedColumnName = "ID", nullable = true)
public TableC getTableC() {
return this.tableC;
}
public void setTableC(TableC tableC) {
this.tableC= tableC;
}
private List<Table2> table2s;
@OneToMany(cascade = {CascadeType.ALL}, orphanRemoval=true, fetch=FetchType.EAGER)
@JoinColumns({
@JoinColumn(name="FK_TABLE_A", referencedColumnName="FK_TABLE_A"),
@JoinColumn(name="FK_TABLE_B", referencedColumnName="FK_TABLE_B")
})
public List<Table2> getTable2s() {
return table2s;
}
public void setTable2s(List<Table2> table2s) {
this.table2s= table2s;
}
@Override
public boolean equals(Object o) {
...
}
@Override
public int hashCode() {
...
}
@Override
public String toString() {
...
}
}
@Embeddable
public class Table1Id extends BaseObject implements Serializable
{
private static final long serialVersionUID = 1L;
private TableA tableA;
private TableB tableB;
@ManyToOne
public TableA getTableA() {
return tableA;
}
public void setTableA(TableA tableA) {
this.tableA = tableA;
}
@ManyToOne
public TableB getTableB() {
return tableB;
}
public void setTableB(TableB tableB) {
this.tableB= tableB;
}
@Override
public boolean equals(Object o) {
...
}
@Override
public int hashCode() {
...
}
@Override
public String toString() {
...
}
}
@Entity
@AssociationOverrides({
@AssociationOverride(name = "pk.tableA",
joinColumns = @JoinColumn(name = "FK_TABLE_A")),
@AssociationOverride(name = "pk.tableB",
joinColumns = @JoinColumn(name = "FK_TABLE_B")),
@AssociationOverride(name = "pk.tableD",
joinColumns = @JoinColumn(name = "FK_TABLE_D")) })
@Table(name="TABLE2")
public class Table2 extends BaseObject implements Serializable
{
private static final long serialVersionUID = 1L;
private Table2Id pk = new Table2Id();
@EmbeddedId
public Table2Id getPk() {
return pk;
}
public void setPk(Table2Id pk) {
this.pk = pk;
}
private Double value;
@Column(name = "VALUE", nullable = false, insertable = true, updatable = true, precision = 2)
@Basic
public Double getValue() {
return this.value;
}
public void setValue(Double value) {
this.goal = goal;
}
@Override
public boolean equals(Object o) {
...
}
@Override
public int hashCode() {
...
}
@Override
public String toString() {
...
}
}
@Embeddable
public class Table2Id extends BaseObject implements Serializable
{
private static final long serialVersionUID = 1L;
private TableA tableA;
@ManyToOne
public TableA getTableA() {
return tableA;
}
public void setTableA(TableA tableA) {
this.tableA= tableA;
}
private TableB tableB;
@ManyToOne
public TableB getTableB() {
return tableB;
}
public void setTableB(TableB tableB) {
this.tableB= tableB;
}
private TableD tableD;
@ManyToOne
public TableD getTableD() {
return this.tableD;
}
public void setTableD(TableD tableD) {
this.tableD= tableD;
}
@Override
public boolean equals(Object o) {
...
}
@Override
public int hashCode() {
...
}
@Override
public String toString() {
...
}
}
通常爲這樣的關係,我只是使用@OneToMany批註的的mappedBy價值,一切工作正常 - 更新,插入和預期的刪除操作執行和期望的。但是,考慮到構建底層表的奇怪方式,我無法做到這一點。只映射到Table2Id(mappedBy =「pk.tableA」或mappedBy =「pk.tableB」)中的單個記錄會導致完全不正確的數據。我需要兩個字段都有適當的匹配,但是我可以告訴我無法在mappedBy中列出多列。 mappedBy =「pk.tableA,pk.tableB」失敗。
我知道我可以通過修改數據庫並向TABLE1添加單個ID主鍵以及向TABLE2添加單個FK_TABLE1主鍵來輕鬆解決此問題。然後,我可以使用@OneToMany的標準方法(mappedBy =「table1」...)。但是我真的希望避免這種情況,如果沒有其他原因,我顯然不需要在數據庫級別這樣做。我希望有一種方法可以告訴Hibernate Table1是所有者,並且Table2的所有更改都依賴於它。