在单独的表中映射 @Embeddable

eja*_*ain 7 java hibernate jpa

两个表如:

CREATE TABLE foo (
  id INT PRIMARY KEY,
  x TEXT
);

CREATE TABLE bar (
  foo_id INT REFERENCES foo (id) ON DELETE CASCADE,
  y TEXT,
  z TEXT
);
Run Code Online (Sandbox Code Playgroud)

...可以像这样映射:

@Table(name = "foo")
@SecondaryTable(name = "bar", pkJoinColumns = @PrimaryKeyJoinColumn(name = "foo_id", referencedColumnName = "id"))
class Foo {

  @Id
  int id;

  @Embedded
  @AttributeOverrides({
    @AttributeOverride(name = "y", column = @Column(table = "bar")),
    @AttributeOverride(name = "z", column = @Column(table = "bar"))
  })
  Bar bar;
}

@Embeddable
class Bar {
  String y;
  String z;
}
Run Code Online (Sandbox Code Playgroud)

有没有一种不那么笨拙的方法来做这个映射,要么只使用标准的 JPA 注释,要么使用 Hibernate 特定的注释(并且不在可嵌入对象中引入父引用)?

将此与@Embeddable使用@ElementCollectionand引用对象集合的容易程度进行比较@CollectionTable

Alv*_*son 5

很抱歉回答晚了,但这个问题让我很感兴趣,所以我想我会尝试一下。

一个更优雅的解决方案是使内容成为barEntity 而不是 Embeddable,并使用 OneToOne 关系而不是 Embedded。您还需要记住使用@PrimaryKeyJoinColumn而不是@JoinColumn

@Entity
@Table(name = "bar")
class Bar {
  @Id
  int fooId;

  String y;
  String z;
}

...

@Entity
@Table(name = "foo")
class Foo {
  @Id
  int id;

  @OneToOne
  @PrimaryKeyJoinColumn
  Bar bar;
}
Run Code Online (Sandbox Code Playgroud)

最大的好处是Foo不再需要了解Bar. 根据数据库的命名策略,您可能还需要指定fooIdin的列名称Bar,例如@Column(name = "foo_id").