Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java hibernate复合主键包含复合外键,如何映射_Java_Hibernate_Hibernate Annotations - Fatal编程技术网

Java hibernate复合主键包含复合外键,如何映射

Java hibernate复合主键包含复合外键,如何映射,java,hibernate,hibernate-annotations,Java,Hibernate,Hibernate Annotations,我在那里搜索,没有找到任何类似的主题,所以我发布了一个新问题 我正在现有数据库上使用Hibernate。我们不允许更改表结构和数据。应用程序正在从数据库读取数据,并根据某些逻辑迁移到另一个数据存储 现在的问题是关于复合PK映射。e、 g 表A有一个复合PK Table A -------- a1 (pk) a2 (pk) a3 (pk) a4 (pk) foo bar ======== 表B也有一个复合PK,这个复合PK的一部分是a的PK,这里也是FK Table B -------- a1

我在那里搜索,没有找到任何类似的主题,所以我发布了一个新问题

我正在现有数据库上使用Hibernate。我们不允许更改表结构和数据。应用程序正在从数据库读取数据,并根据某些逻辑迁移到另一个数据存储

现在的问题是关于复合PK映射。e、 g

表A有一个复合PK

Table A
--------
a1 (pk)
a2 (pk)
a3 (pk)
a4 (pk)
foo
bar
========
表B也有一个复合PK,这个复合PK的一部分是a的PK,这里也是FK

Table B
--------
a1 (fk,pk)
a2 (fk,pk)
a3 (fk,pk)
a4 (fk,pk)
b1 (pk)
b2 (pk)
b3 (pk)
foo
bar
========

我尝试了几种方法,但没有一种有效。谁能说出一个有效的Hibernate映射解决方案?注释样式更好。

在B的pk类中将A的实体对象设置为@ManyToOne

所以如果你有

Class A
Class APK - A's Primary Key

Class B
Class BPK - B's primary Key.
BPK
将包含
A
作为属性

@Embeddable
public class BPK implements serializable {
  ....
  private A a;

  @ManyToOne(fetch=FetchType.EAGER)
  @JoinColumns ({
    @JoinColumn(name="...", referencedColumnName = "..."),
    @JoinColumn(name="...", referencedColumnName = "..."),
    ...
  })
  public getA() {
    return this.a;
  }
}

@Embeddeble继承的访问类型为 它所拥有的实体,除非休眠 特定注释@AccessType为 用过。复合外键(如果不是 使用默认敏感值) 使用 @JoinColumns元素,它是 基本上是@JoinColumn的数组。信息技术 这被认为是一个很好的实践 表示引用的列名称 明确地否则,Hibernate将 假设您使用相同的顺序 与主键中相同的列 声明


如果复合主键只有代理键,请使用@EmbeddableId

@Embeddable
public class CompoundIdA implements Serializable {

    private Integer field0;
    private Integer field1;
    private Integer field2;
    private Integer field3;

    @Column(name="FIELD_0")
    public Integer getField0() {
        return this.field0;
    }

    @Column(name="FIELD_1")
    public Integer getField1() {
        return this.field1;
    }

    @Column(name="FIELD_2")
    public Integer getField2() {
        return this.field2;
    }

    @Column(name="FIELD_3")
    public Integer getField3() {
        return this.field3;
    }

    public boolean equals(Object o) {
        if(o == null)
            return false;

        if(!(o instanceof CompoundIdA))
            return false;

        final CompoundIdA other = (CompoundIdA) o;
        if(!(getField0().equals(other.getField0()))
            return false;

        if(!(getField1().equals(other.getField1()))
            return false;

        if(!(getField2().equals(other.getField2()))
            return false;

        if(!(getField2().equals(other.getField2()))
            return false;

        return true;
    }

    // hashcode impl

}
// Let's suppose field0 and field1 are both natural keys
@Entity
public class ClassA {

    private CompoundIdA compoundIdA;

    private Integer field0;
    private Integer field1;

    @EmbeddedId
    public CompoundIdA getCompoundIdA() {
        return this.CompoundIdA;
    }

    @Column(name="FIELD_0", insertable=false, updateable=false)
    public Integer getField0() {
        return this.field0;
    }

    @Column(name="FIELD_1", insertable=false, updateable=false)
    public Integer getField1() {
        return this.field1;
    }

}
在A班,我们有

@Entity
public class ClassA {

    private CompoundIdA compoundIdA;

    @EmbeddedId
    public CompoundIdA getCompoundIdA() {
        return this.CompoundIdA;
    }

}

如果复合主键同时具有自然键和代理键,请再次使用@EmbeddableId

@Embeddable
public class CompoundIdA implements Serializable {

    private Integer field0;
    private Integer field1;
    private Integer field2;
    private Integer field3;

    @Column(name="FIELD_0")
    public Integer getField0() {
        return this.field0;
    }

    @Column(name="FIELD_1")
    public Integer getField1() {
        return this.field1;
    }

    @Column(name="FIELD_2")
    public Integer getField2() {
        return this.field2;
    }

    @Column(name="FIELD_3")
    public Integer getField3() {
        return this.field3;
    }

    public boolean equals(Object o) {
        if(o == null)
            return false;

        if(!(o instanceof CompoundIdA))
            return false;

        final CompoundIdA other = (CompoundIdA) o;
        if(!(getField0().equals(other.getField0()))
            return false;

        if(!(getField1().equals(other.getField1()))
            return false;

        if(!(getField2().equals(other.getField2()))
            return false;

        if(!(getField2().equals(other.getField2()))
            return false;

        return true;
    }

    // hashcode impl

}
// Let's suppose field0 and field1 are both natural keys
@Entity
public class ClassA {

    private CompoundIdA compoundIdA;

    private Integer field0;
    private Integer field1;

    @EmbeddedId
    public CompoundIdA getCompoundIdA() {
        return this.CompoundIdA;
    }

    @Column(name="FIELD_0", insertable=false, updateable=false)
    public Integer getField0() {
        return this.field0;
    }

    @Column(name="FIELD_1", insertable=false, updateable=false)
    public Integer getField1() {
        return this.field1;
    }

}
请注意,您必须设置insertable=false和updateable=false,因为有多个属性共享同一列。否则,Hibernate将抱怨一些错误


如果复合主键只有自然键,请使用@IdClass

@Entity
@IdClass(CompoundIdA.class)
public class ClassA {

    private Integer field0;
    private Integer field1;
    private Integer field2;
    private Integer field3;

    @Id
    @Column(name="FIELD_0")
    public Integer getField0() {
        return this.field0;
    }

    @Id
    @Column(name="FIELD_1")
    public Integer getField1() {
        return this.field1;
    }

    @Id
    @Column(name="FIELD_2")
    public Integer getField2() {
        return this.field2;
    }

    @Id
    @Column(name="FIELD_3")
    public Integer getField3() {
        return this.field3;
    }

}
在ClassB中,您可以使用与上面所示相同的方法,但是如果您想要定义@manytone属性,您必须设置insertable=false和updateable=false,如下所示

@Entity
public class ClassB {

    private ClassA classA;

    @ManyToOne
    @JoinColumns ({
        @JoinColumn(name="FIELD_0", referencedColumnName="FIELD_0", insertable=false, updateable=false),
        @JoinColumn(name="FIELD_1", referencedColumnName="FIELD_1", insertable=false, updateable=false),
        @JoinColumn(name="FIELD_2", referencedColumnName="FIELD_2", insertable=false, updateable=false),
        @JoinColumn(name="FIELD_3", referencedColumnName="FIELD_3", insertable=false, updateable=false)
    })
    public ClassA getClassA() {
        return this.classA;
    }

}

您好,

我真的看不出您的答案和我的答案有什么不同。除了您对我概述的相同内容使用了替代注释之外。我如何为相同内容编写ClassB.hbm.xml?@Vinodh Ramasubramania嗨,使用实体作为主键不是一个好主意。Hibernate团队确实推荐。不能跨用作主键的实体限制HQL中的查询结果或条件。因此,有很多方法可以避免使用它,但我不使用实体作为PK。我使用它(A)与B的PK中的连接条件建立多通关系。在您的解决方案中,我看不出B的复合PK(BPK)是如何定义为A的复合PK(APK)的子集的。BPK类中的一通可以帮助我。我没有朝那个方向想。我一直在想如何引用BPK中的另一个APK类。不知道如何设置注释。为了方便起见,我在一个类中建模了另一个带有joincolumns的One2Many。e、 g.专用集bSet;。在TypeB类中,也是一个指向TypeA的多音字。当然,需要insertable、updateable=false。谢谢你们。