【问题标题】:H2 index name uniquenessH2索引名称唯一性
【发布时间】:2015-11-18 20:38:34
【问题描述】:

我对 h2 数据库中索引名称的唯一性有一个小问题。使用 mysql/mariadb 可以同时为表 A 和表 B 定义名为“X”的索引。使用 h2 数据库是不可能的,因为每个数据库的索引名称应该是唯一的。

这对我来说是个问题,因为我有一个定义了以下属性的基本 JPA 实体类:

@org.hibernate.annotations.Index(name = "X")
protected String x;

它被A类和B类继承,B类的索引创建失败,错误如下:

ERROR [main] o.h.tool.hbm2ddl.SchemaUpdate   - HHH000388: Unsuccessful: create index X on B(x)
ERROR [main] o.h.tool.hbm2ddl.SchemaUpdate   - Index "X" already exists

是否可以告诉 hibernate 自动创建索引名或以某种方式为 H2 创建一个适配器,该适配器将在此类索引名前加上表名?

【问题讨论】:

  • 看来你运气不好。我也会小心将索引定义为注释。它们更容易分开处理。

标签: java hibernate jpa orm h2


【解决方案1】:

虽然您应该始终拥有 database drive the schema evolution 并使用 FlywayDB 迁移架构版本,但您可以根据需要覆盖 @Index。

我添加了test on GitHub 来证明这一点。

类如下所示:

@Entity(name = "Base")
@Table(name="Base")
@Inheritance(strategy = InheritanceType.JOINED)
public static abstract class Base {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Transient
    protected String x;

    public Long getId() {
        return id;
    }

    public String getX() {
        return x;
    }

    public void setX(String x) {
        this.x = x;
    }
}

@Entity(name = "ChildY")
@Table(name="ChildY")
@DiscriminatorValue("Y")
public static class ChildY extends Base {

    private String y;

    @Override
    @org.hibernate.annotations.Index(name = "xy")
    @Access(AccessType.PROPERTY)
    public String getX() {
        return x;
    }
}

@Entity(name = "ChildZ")
@Table(name="ChildZ")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorValue("Z")
public static class ChildZ extends Base {

    private String z;

    @Override
    @org.hibernate.annotations.Index(name = "xz")
    @Access(AccessType.PROPERTY)
    public String getX() {
        return x;
    }
}

架构是这样生成的:

create table Base (id bigint generated by default as identity (start with 1), primary key (id))
create table ChildY (x varchar(255), y varchar(255), id bigint not null, primary key (id))
create table ChildZ (x varchar(255), z varchar(255), id bigint not null, primary key (id))
create index xy on ChildY (x)
create index xz on ChildZ (x)

这边:

  1. 您保留域模型中的基类属性(字段、getter 和 setter)
  2. 每个表都有自己的 x 列和关联的索引

问题是您不能在基类中拥有该字段,因为 Hibernate 将尝试创建它两次。您可以在 Hibernate 上提交 Jira 问题并提及 HBM 模式生成应该跳过索引(如果它已经创建)。

最优雅的解决方案是简单地使用适当的数据库架构并删除 HBM-DDL 架构生成。

【讨论】:

  • 这是我所期望的。非常感谢!
猜你喜欢
  • 2019-01-01
  • 1970-01-01
  • 2018-07-28
  • 1970-01-01
  • 2020-06-28
  • 2015-05-04
  • 2020-11-13
  • 2011-09-24
  • 2022-01-02
相关资源
最近更新 更多