Java 使用不匹配的复合主键休眠OneToMany

Java 使用不匹配的复合主键休眠OneToMany,java,hibernate,oracle11g,Java,Hibernate,Oracle11g,我的数据库中有两个表,它们通过复合主键/外键映射在一起,让Hibernate处理它们花了我很多时间。我的数据库如下所示: 表1有一个由外键组成的复合主键,映射到表a和表B。表2也有一个由外键组成的复合主键,映射到表a、表B和表D。在数据库中,表2只使用前两个外键映射回表1。没问题。把这个翻译成Hibernate让我很难受 因为TABLE2需要一个包含三列的嵌入式id,所以我不能使用@OneToMany注释的mappedBy参数。我得到了与主键列不匹配的外键数的预期错误。因此,我改用@JoinC

我的数据库中有两个表,它们通过复合主键/外键映射在一起,让Hibernate处理它们花了我很多时间。我的数据库如下所示:

表1有一个由外键组成的复合主键,映射到表a和表B。表2也有一个由外键组成的复合主键,映射到表a、表B和表D。在数据库中,表2只使用前两个外键映射回表1。没问题。把这个翻译成Hibernate让我很难受

因为TABLE2需要一个包含三列的嵌入式id,所以我不能使用@OneToMany注释的mappedBy参数。我得到了与主键列不匹配的外键数的预期错误。因此,我改用@JoinColumns。这对于拯救新的实体非常有效。然而,当我试图从表2中删除一些映射时,我遇到了一个问题,Hibernate试图在删除之前更新表2,将FK_TABLE_A设置为null,这显然是不允许的。我所能找到的最好结果是,在映射xml中使用reverse=“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() {
        ...
    }
}
@实体
@联想超越({
@AssociationOverride(name=“pk.tabla”,
joinColumns=@JoinColumn(name=“FK_TABLE_A”),
@AssociationOverride(name=“pk.tableB”,
joinColumns=@JoinColumn(name=“FK_TABLE_B”)})
@表(name=“表1”)
公共类Table1扩展BaseObject实现可序列化
{
私有静态最终长serialVersionUID=1L;
private Table1Id pk=new Table1Id();
@嵌入ID
公共表1id getPk(){
返回主键;
}
公共无效设置主键(表1ID主键){
this.pk=pk;
}
私人表格;
@许多酮
@JoinColumn(name=“FK\u TABLE\u C”,referencedColumnName=“ID”,nullable=true)
公共表c getTableC(){
返回此表c;
}
公共空间设置表C(表C表C){
表C=表C;
}
私人名单表2;
@OneToMany(cascade={CascadeType.ALL},orphanRemoving=true,fetch=FetchType.EAGER)
@连接柱({
@JoinColumn(name=“FK_TABLE_A”,referencedColumnName=“FK_TABLE_A”),
@JoinColumn(name=“FK_TABLE_B”,referencedColumnName=“FK_TABLE_B”)
})
公共列表getTable2s(){
返回表2;
}
公共无效设置表2(列表表2){
表2s=表2s;
}
@凌驾
公共布尔等于(对象o){
...
}
@凌驾
公共int hashCode(){
...
}
@凌驾
公共字符串toString(){
...
}
}
@可嵌入
公共类Table1Id扩展BaseObject实现可序列化
{
私有静态最终长serialVersionUID=1L;
私人表格;
私人附表b附表b;
@许多酮
公共表格a getTableA(){
返回表a;
}
公共空间设置表A(表A表A){
这个表a=表a;
}
@许多酮
公共表b getTableB(){
返回表b;
}
公共无效设置表B(表B表B){
表B=表B;
}
@凌驾
公共布尔等于(对象o){
...
}
@凌驾
公共int hashCode(){
...
}
@凌驾
公共字符串toString(){
...
}
}
@实体
@联想超越({
@AssociationOverride(name=“pk.tabla”,
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”)})
@表(name=“表2”)
公共类Table2扩展BaseObject实现可序列化
{
私有静态最终长serialVersionUID=1L;
私有Table2Id pk=新Table2Id();
@嵌入ID
公共表2id getPk(){
返回主键;
}
公共无效设置主键(表2ID主键){
this.pk=pk;
}
私人双重价值;
@列(name=“VALUE”,nullable=false,insertable=true,updateable=true,precision=2)
@基本的
公共双getValue(){
返回此.value;
}
公共无效设置值(双值){
这个。目标=目标;
}
@凌驾
公共布尔等于(对象o){
...
}
@凌驾
公共int hashCode(){
...
}
@凌驾
公共字符串toString(){
...
}
}
@可嵌入
公共类Table2Id扩展BaseObject实现可序列化
{
私有静态最终长serialVersionUID=1L;
私人表格;
@许多酮
公共表格a getTableA(){
返回表a;
}
公共空间设置表A(表A表A){
表A=表A;
}
私人附表b附表b;
@许多酮
公共表b getTableB(){
返回表b;
}
公共无效设置表B(表B表B){
表B=表B;
}
私人会议;
@许多酮
公共表格getTableD(){
把这个放回桌上;
}
已设置公共无效(已提交){
这个.tableD=tableD;
}
@凌驾
公共布尔等于(对象o){
...
}
@凌驾
公共int hashCode(){
...
}
@凌驾
公共字符串toString(){
...
}
}
通常对于这样的关系,我只使用@OneToMany注释的mappedBy值,一切正常-更新、插入和删除按预期和所需执行。但是,考虑到底层表的构造方式非常奇怪,我无法做到这一点。仅映射到Table2Id中的单个记录(mappedBy=“pk.tableA”或mappedBy=“pk.tableB”)将导致数据完全不正确。我要求两个字段都有一个适当的
@Entity
@AssociationOverrides({
        @AssociationOverride(name = "pk.tableA",
                joinColumns = @JoinColumn(name = "FK_TABLE_A", nullable=false)),
        @AssociationOverride(name = "pk.tableB",
                joinColumns = @JoinColumn(name = "FK_TABLE_B", nullable=false)) })
@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(mappedBy="pk.table1", cascade = {CascadeType.ALL}, orphanRemoval=true, fetch=FetchType.EAGER)
    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() {
        ...
    }
}

@Entity
@AssociationOverrides({
        @AssociationOverride(name = "pk.table1",
                joinColumns = {
                        @JoinColumn(name = "FK_TABLE_A", nullable=false, insertable=false, updatable=false),
                        @JoinColumn(name = "FK_TABLE_B", nullable=false, insertable=false, updatable=false)
                        }),
        @AssociationOverride(name = "pk.tableD",
                joinColumns = @JoinColumn(name = "FK_TABLE_D", nullable=false)) })
@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.value = value;
    }

    @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 Table1 table1;
    @ManyToOne
    @JoinColumn(nullable=false)
    public Table1 getTable1() {
        return this.table1;
    }
    public void setTable1(Table1 table1) {
        this.table1 = table1;
    }

    private TableD tableD;
    @ManyToOne
    @JoinColumn(nullable=false)
    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() {
        ...
    }
}