spring - hibernate 说表不存在,但它正在创建表
问题描述
我正在开发一个 Spring 应用程序,并且我将 JPA 与 MariaDB 一起用于我的数据库。当应用程序启动时,它首先会抛出一些关于不存在的表的异常,但它会创建它们。错误后应用程序不会终止。
难道我做错了什么?
更新:
当我改变
spring.jpa.hibernate.ddl-auto=create-drop
至
spring.jpa.hibernate.ddl-auto=update
hibernate 不再抛出异常。
为什么?
日志总结:
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table roles_privileges drop foreign key FK5yjwxw2gvfyu76j3rgqwo685u" via JDBC Statement
...
Caused by: java.sql.SQLSyntaxErrorException: (conn=105) Table 'users.roles_privileges' doesn't exist
...
Caused by: java.sql.SQLException: Table 'users.roles_privileges' doesn't exist
...
2019-10-29 18:13:00.866 WARN 821 --- [ main] o.h.t.s.i.ExceptionHandlerLoggedImpl : GenerationTarget encountered exception accepting command : Error executing DDL "alter table roles_privileges drop foreign key FK9h2vewsqh8luhfq71xokh4who" via JDBC Statement
...
Caused by: java.sql.SQLSyntaxErrorException: (conn=105) Table 'users.roles_privileges' doesn't exist
用户实体:
@Entity
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Email
private String email;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String password;
@ManyToMany
@JoinTable(
name = "users_roles",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "username"),
inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "name"))
private Collection<Role> roles;
...
}
角色实体:
@Entity
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(unique = true, nullable = false)
private String name;
@ManyToMany(mappedBy = "roles")
private Collection<User> users;
@ManyToMany
@JoinTable(name = "roles_privileges",
joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "privilege_id", referencedColumnName = "id")
)
private Collection<Privilege> privileges;
...
}
特权实体:
@Entity
public class Privilege {
@Id
private long id;
@Column(unique = true, nullable = false)
private String name;
@ManyToMany(mappedBy = "privileges")
private Collection<Role> roles;
....
}
应用程序属性
#User datasource
spring.datasource.url=jdbc:mariadb://localhost:3306/users
spring.datasource.username=user01
spring.datasource.password=user01pass
#`hibernate_sequence' doesn't exist
spring.jpa.hibernate.use-new-id-generator-mappings=false
spring.jpa.hibernate.ddl-auto=create-drop
解决方案
你可能没有做错任何事。
当您将 Hibernate 的 hbm2ddl auto 与create
or一起使用时create-drop
,Hibernate 将尝试在启动时创建您的数据库模式。
您可以打开您的show-sql
属性application.properties
以查看生成的 SQL 查询:
spring.jpa.show-sql=true
查询可能如下所示:
alter table `your_table` drop foreign key `FK...`
drop table if exists `your_table`
create table `your_table` (...)
alter table `your_table` add constraint `UK...` unique (`name`)
alter table `your_table` add constraint `FK...` foreign key (`foreign_id`) references `other_table` (`id`)
首先 Hibernate 删除外键约束,然后删除表,然后创建表,然后对其添加约束。
该错误发生在第一个查询中,当尝试删除外键并且表还不存在时。没有什么不好的事情发生,您可以忽略错误,其他查询将起作用并且表将被正确创建。
据我所知,MySQL 和 MariaDB 不支持“如果表存在则删除外键”之类的东西,这将有助于抑制错误。
推荐阅读
- javascript - Slick.js carousel - swipeToSlide 只允许滚动 2 个或更多幻灯片
- c# - SQL Server:在 Linq 连接条件中实现“IN(...)”
- c# - Microsoft Graph 的 OAuth 提示在 Bot Framework Emulator 中不显示提示
- unity3d - Unity 和 VR:使用“ReadPixels()”函数进行偏移
- javascript - 为什么不在类外部/顶部声明变量以避免使用此关键字?
- batch-file - 检查变量是否为文本文件
- python - if 和 elif 问题:哪一个是有效的?
- typescript - 指一种类型,但在这里用作值
- numpy - 如何从张量流分类模型中获得一系列预测
- postgresql - 使用 CI/CD 中的 Flyway 在 Docker 中填充/播种 Postgres DB,然后标记并发布新的 docker 映像以用于测试