Hibernate ManyToOne映射嵌入的NaturalId

时间:2018-06-04 14:16:41

标签: java hibernate composite-key naturalid

我有主键和复合自然ID的实体设置。所以通常我想使用主键进行关系。但是这些实体在其复合自然ID中共享列,我想重用这些列作为它们的关系。在这种情况下使用人工pk会破坏正常形式。

Hibernate版本 5.2.17

我的实体(让我们将它们命名为Module and Submodule)设置如下:

@Data @Entity
public class Module {

  @Id @Column(name = "module_id", nullable = false, unique = true)
  private int moduleId;

  @Embedded @NaturalId @AttributeOverrides({
        @AttributeOverride(name = "module_number", column = @Column(name = "module_number")),
        @AttributeOverride(name = "module_code", column = @Column(name = "module_code"))
  })
  private ModuleNumber number;

  @OneToMany(mappedBy = "module")
  private Set<Submodule> submodules;
}
@Data @Entity
public class Submodule {

  @Id @Column(name = "submodule_id", nullable = false, unique = true)
  private int submoduleId;

  @Embedded @NaturalId @AttributeOverrides({
        @AttributeOverride(name = "module_number", column = @Column(name = "module_number")),
        @AttributeOverride(name = "module_code", column = @Column(name = "module_code")),
        @AttributeOverride(name = "submodule_number", column = @Column(name = "submodule_number"))
  })
  private SubmoduleNumber number;

  @ManyToOne
  @JoinColumns(value = {
        @JoinColumn(name = "module_number", referencedColumnName = "module_number", nullable = false, insertable = false, updatable = false),
        @JoinColumn(name = "module_code", referencedColumnName = "module_code", nullable = false, insertable = false, updatable = false)
  }, foreignKey = @ForeignKey(name = "fk_Submodule_Module"))
  private Module module;
}

可嵌入课程:

@Getter @Setter
@Embeddable
@MappedSuperclass
public class ModuleNumber {

  @Column(name = "module_number", nullable = false)
  protected int moduleNumber;

  @Column(name = "module_code", nullable = false)
  protected char moduleCode;
}
@Getter @Setter
@Embeddable
public class SubmoduleNumber extends ModuleNumber {

  @Column(name = "submodule_number", nullable = false)
  private int submoduleNumber;
}

在此之前我使用复合自然id作为复合主键(通过EmbeddedId)测试的设置就好了。尽管决定在所有关系中使用复合键并没有真正产生任何好处,因为它们使代码和ddl可读性混乱并可能影响性能。 但在少数情况下,列已经存在,我想重用它们。特别是因为这种结构更深入了一些元素。

使用hibernates架构更新运行此命令会导致以下错误:

org.hibernate.AnnotationException:
referencedColumnNames(module_number, module_code) of Submodule.module
referencing Module not mapped to a single property

所以我的问题是:

  1. 我的方法是否合理还是有更简单的解决方案?
  2. Hibernate甚至可以实现这一点吗?
  3. 在这种情况下我做错了什么,以及如何在Hibernate中工作?

0 个答案:

没有答案