我正在开发一个 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
或 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 不支持“如果表存在则删除外键”之类的东西,这有助于抑制错误。
关于spring - hibernate 说表不存在但它正在创建表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58610089/