java 具有复合主键的一部分的休眠外键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32625410/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 20:30:46  来源:igfitidea点击:

Hibernate foreign key with a part of composite primary key

javahibernateforeign-keyscomposite-keycomposite-primary-key

提问by Jagger


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:


我必须与 Hibernate 一起工作,但我不太确定如何解决这个问题,我有 2 个具有 1..n 关系的表,如下所示:

-------
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?

如何使用 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.

我的数据库模式是从 Hibernate 模型生成的。

采纳答案by Jagger

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 Bentity as composite key containing col_a, col_b, and col_cand what was supposed to be the primary key in the first place, define as unique constraint. The disadvantage is that the column col_cis not really conceptually a part of primary key.

B实体的主键定义为包含col_a,col_b和 的复合键,以及col_c最初应该是主键的内容,定义为唯一约束。缺点是该列col_c在概念上并不是主键的一部分。

@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 @EmbeddedIdand @MapsIdannotations and does exactly what I wanted to be done at the very beginning.

第二个使用@EmbeddedId@MapsId注释并完全按照我一开始就想做的事情做。

@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;
}

回答by Xiaofeng Li

Jagger's second solution that is my first reaction, with @EmbededId and @MapsId. The following is another way based on his second solution but without using @MapsId. `

Jagger 的第二个解决方案是我的第一反应,@EmbededId 和 @MapsId。以下是基于他的第二个解决方案但不使用@MapsId 的另一种方法。`

@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;

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