使用复合主键的一部分休眠外键


我必须使用 Hibernate,但我不太确定如何解决这个问题,我有 2 个表,其 1..n 关系如下:

<上一页>--------表_A--------col_b (pk)col_c (pk)[其他领域]--------表_B--------col_a (pk)col_b (pk) (fk TABLE_A.col_b)col_c (fk TABLE_A.col_c)[其他领域]

我如何使用 Hibernate 来管理这个?

我不知道如何声明包含主键一部分的外键.

我的数据库架构是从 Hibernate 模型生成的.

解决方案

这个问题我找到了两个解决方案.

第一个是一种解决方法,不如第二个那么整洁.

B实体的主键定义为包含col_acol_bcol_c的复合键,并且首先应该是主键,定义为唯一约束.缺点是列 col_c 在概念上并不是主键的一部分.

@EntityA类{@ID私人int b;@ID私人int c;}@实体@Table(uniqueConstraints = {@UniqueConstraint(columnNames = { "a", "b" }) })B类{@ID私人int a;@ID@ManyToOne(可选=假)@JoinColumns(值 = {@JoinColumn(name = "b", referencedColumnName = "b"),@JoinColumn(name = "c", referencedColumnName = "c") })私人A实体A;}

第二个使用 @EmbeddedId@MapsId 注释,完全符合我一开始就想做的事情.

@EntityA类{@ID私人int b;@ID私人int c;}@可嵌入类 BKey {私人int a;私人int b;}@实体B类{@EmbeddedId私有 BKey 主键;@MapsId("b")@ManyToOne(可选=假)@JoinColumns(值 = {@JoinColumn(name = "b", referencedColumnName = "b"),@JoinColumn(name = "c", referencedColumnName = "c") })私人A实体A;}


I have to work with Hibernate and I am not very sure how to solve this problem, I have 2 tables with a 1..n relationship like this:

-------
TABLE_A
-------
col_b (pk)
col_c (pk)
[other fields]

-------
TABLE_B
-------
col_a (pk)
col_b (pk) (fk TABLE_A.col_b)
col_c (fk TABLE_A.col_c)
[other fields]

How can I manage this with Hibernate?

I do not have any idea how to declare a foreign key that would contain a part of primary key.

My database schema is generated from the Hibernate model.

解决方案

I have found two solutions to this problem.

The first one is rather a workaround and is not so neat as the second one.

Define the primary key of the B entity as composite key containing col_a, col_b, and col_c and what was supposed to be the primary key in the first place, define as unique constraint. The disadvantage is that the column col_c is not really conceptually a part of primary key.

@Entity
class A {
  @Id
  private int b;
  @Id
  private int c;
}

@Entity
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = { "a", "b" }) })
class B {
  @Id
  private int a;

  @Id
  @ManyToOne(optional = false)
  @JoinColumns(value = {
          @JoinColumn(name = "b", referencedColumnName = "b"),
          @JoinColumn(name = "c", referencedColumnName = "c") })
  private A entityA;
}

The second uses @EmbeddedId and @MapsId annotations and does exactly what I wanted to be done at the very beginning.

@Entity
class A {
  @Id
  private int b;
  @Id
  private int c;
}

@Embeddable
class BKey {
  private int a;
  private int b;
}

@Entity
class B {
  @EmbeddedId
  private BKey primaryKey;

  @MapsId("b")
  @ManyToOne(optional = false)
  @JoinColumns(value = {
          @JoinColumn(name = "b", referencedColumnName = "b"),
          @JoinColumn(name = "c", referencedColumnName = "c") })
  private A entityA;
}

相关文章