org.flywaydb唯一约束问题

时间:2018-02-08 07:01:49

标签: hibernate oracle11g flyway

我是Flyway的新手。我正在使用JPA和基于注释的配置来定义数据库映射。

下面是具有属性的唯一键的实体类。

@Entity
@Table(name = "Test", uniqueConstraints = @UniqueConstraint(columnNames = "YEAR"))
public class Test
{
    private static final long   serialVersionUID    = 1L;
    @Column(nullable = false, name = "YEAR")
    private Long                year;
  // setter and getter
}

从maven我使用hibernate:update它将创建成功的迁移脚本sql文件。 (test_script.sql)

下面是生成的test_script.sql: 由hibernate:upadate maven命令生成的脚本:

// create table command
create table Test(ID number(19,0) not null, year number(19,0) not null, primary key (ID));
// Alter table command
alter table Test drop constraint UK_12131231231;
// Alter table command
alter table Test add constraint UK_12131231231unique (year);

当我触发flyway:migrate maven命令时,我得到消息:

Error code after the flyway:migrate :

SQL State  : 72000
Error Code : 2443
Message    : ORA-02443: Cannot drop constraint  - nonexistent constraint
Statement  : alter table Test drop constraint UK_12131231231;

如果有人遇到同样的问题并且有相同的解决方案,我会很坦白。

2 个答案:

答案 0 :(得分:0)

嗯,那是因为你没有命名主键约束但让Oracle使用自己的算法创建它 - 这就是为什么它的名字是UK_12131231231(数字串)。

这是一个示范:

SQL> create table test (id number, primary key (id));

Table created.

SQL> select constraint_name from user_constraints where table_name = 'TEST';

CONSTRAINT_NAME
------------------------------
SYS_C0045805

SQL>

我现在放下桌子重新创建它;请注意,约束名称已更改:

SQL> drop table test;

Table dropped.

SQL> create table test (id number, primary key (id));

Table created.

SQL> select constraint_name from user_constraints where table_name = 'TEST';

CONSTRAINT_NAME
------------------------------
SYS_C0045806

SQL>

因此,DROP CONSTRAINT命令中的硬编码约束名称并不是一个好主意,因为它每次都会更改。

我建议您将约束命名为:

SQL> create table test (id number, constraint pk_test primary key (id));

Table created.

SQL> select constraint_name from user_constraints where table_name = 'TEST';

CONSTRAINT_NAME
------------------------------
PK_TEST

SQL> alter table test drop constraint pk_test;

Table altered.

SQL>

啊哈!这有点不同!约束名称将始终为PK_TEST,您可以在脚本中自由硬编码,因为它的名称不会改变而您不会获得{{ 1}}

答案 1 :(得分:0)

要避免自动生成的约束名称(可能不同),您应自行命名:

@Entity
@Table(name = "Test",
 uniqueConstraints = @UniqueConstraint(name="UQ_TEST_YEAR", columnNames = "YEAR")
)
...