好吧,我有一个使用Hibernate(5.0.12.Final)的Spring Boot应用程序(1.5.2.RELEASE),我遇到一些问题,Hibernate无法在启动时正确地重新创建我的数据库
我将Hibernate配置为在启动时再次创建表:
spring.jpa.hibernate.ddl-auto=create
这是我的第一个实体(客户):
@Entity
public class Client {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private String name;
@NotNull
private String firstName;
@Email
@NotNull
private String email;
@Valid
@Embedded
private Credentials credentials = new Credentials();
@OneToMany(mappedBy = "client")
private List<Reservation> reservations = new ArrayList<>();
//Getters, Setters, hashcode & equals omitted
}
预订实体:
@Entity
public class Reservation {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private Client client;
@Enumerated(EnumType.STRING)
private State state = State.UNTREATED;
//Getters, Setters, hashcode & equals omitted
}
以下是创建的数据库的概述:
这是控制台输出,为了简单起见,我试图将其缩写为:
INFO : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
INFO : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
INFO : HHH000227: Running hbm2ddl schema export
Hibernate: alter table reservation drop foreign key FKoewar6f18rkn4iptr6da4oysv
ERROR : HHH000389: Unsuccessful: alter table reservation drop foreign key FKoewar6f18rkn4iptr6da4oysv
ERROR : Can't DROP 'FKoewar6f18rkn4iptr6da4oysv'; check that column/key exists
Hibernate: drop table if exists client
ERROR : HHH000389: Unsuccessful: drop table if exists client
ERROR : Cannot delete or update a parent row: a foreign key constraint fails
Hibernate: drop table if exists reservation
Hibernate: drop table if exists restaurant
Hibernate: create table client (id bigint not null auto_increment, created_on datetime, credentials_version integer not null, hash varchar(255), username varchar(255), email varchar(255) not null, first_name varchar(255) not null, name varchar(255) not null, primary key (id))
ERROR : HHH000389: Unsuccessful: create table client (id bigint not null auto_increment, created_on datetime, credentials_version integer not null, hash varchar(255), username varchar(255), email varchar(255) not null, first_name varchar(255) not null, name varchar(255) not null, primary key (id))
ERROR : Table 'client' already exists
Hibernate: create table reservation (id bigint not null auto_increment, state varchar(255), client_id bigint, primary key (id))
Hibernate: create table restaurant (id bigint not null auto_increment, primary key (id))
Hibernate: alter table reservation add constraint FKoewar6f18rkn4iptr6da4oysv foreign key (client_id) references client (id)
INFO : HHH000230: Schema export complete
INFO : Initialized JPA EntityManagerFactory for persistence unit 'default'
INFO : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
INFO : HHH000227: Running hbm2ddl schema export
ERROR : HHH000389: Unsuccessful: alter table `Reservation` drop foreign key `FK8gjvlt7rp8i9kp7rdmn107ni7`
ERROR : Can't DROP 'FK8gjvlt7rp8i9kp7rdmn107ni7'; check that column/key exists
ERROR : HHH000389: Unsuccessful: drop table if exists `Client`
ERROR : Cannot delete or update a parent row: a foreign key constraint fails
ERROR : HHH000389: Unsuccessful: create table `Client` (`id` bigint not null auto_increment, `createdOn` datetime, `credentialsVersion` integer not null, `hash` varchar(255), `username` varchar(255), `email` varchar(255) not null, `firstName` varchar(255) not null, `name` varchar(255) not null, primary key (`id`))
ERROR : Table 'client' already exists
INFO : HHH000230: Schema export complete
我不知道它是否重要但MySQL数据库版本是在Windows上运行的5.7.13。此外,我没有包括餐厅实体和可嵌入的凭证。
我觉得奇怪的是,Hibernate试图删除一个先不存在的外键,然后删除正确的外键并且都失败(如果我正确读取它)。
这背后的原因是什么?以及如何预防这些问题?
我已经查看了其他相关的SO问题,但它们通常是由无效名称或类似问题引起的,但我认为我的命名没有任何问题。我也尝试用“tbl_”为我的所有表添加前缀,并使用前缀重命名一些列,以防万一引起冲突但没有运气。
这让我很烦,因为数据库没有正确更新,在活动开发期间我不想每次都手动删除/创建模式。也许值得一提的是,即使架构是空的,在启动时,hibernate会给出错误,但事情并不存在。
答案 0 :(得分:0)
试试吧。我认为预订中的问题
@ManyToOne
@JoinColumn(name = "client_id")
private Client client;
答案 1 :(得分:0)
首先,您应该了解如何生成外键约束名称:
How does hibernate generate foreign key constraint names?
因此,如果更改表或外键列名,则将具有不同的外键约束名称,并且Hibernate将无法删除旧的外键约束。
你能做什么:
使用指定外部约束名称
@javax.persistence.ForeignKey
注释(不要混淆
@org.hibernate.annotations.ForeignKey
,虽然可以使用它
到)。
使用spring.jpa.hibernate.ddl-auto = update
更新架构,
不要每次都重新创建它。
使用命名策略生成外键名称(仅适用于Hibernate 5)。但是您需要考虑如何组合表,关联表,列名称以不经常更改外部约束名称:Need help in implementing ImplicitNamingStrategy for foreign key column names in Hibernate 5