spring - hibernate 说表不存在但它正在创建表

标签 spring hibernate jpa

我正在开发一个 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 与 createcreate-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/

相关文章:

hibernate - 如何在JPA中进行批量插入?

spring - 使用自定义 AnnotationTransactionAttributeSource 和 tx :annotation-driven

java - 如何使用java + spring代码连接MFT服务器与其余暴露的执行上传,下载和列出文件等操作

java - 带有 Mongodb 源的 Spring 批处理项目读取器 : How to convert DBObject to a custom POJO in the ItemReader?

java - 如何在 Eclipse 中使用 Hibernate Tools 生成 DAO?

java - 使用启用了符合 JPA 的事务访问的 JTA 时无法访问事务

java - Spring Batch - 为什么作业步骤 bean 是在 Web 上下文而不是作业上下文中创建/执行的?

java - 在 Spring Boot 中重新创建查询

java - 如何在mysql数据库中创建表时忽略实体类中的字段?

hibernate - 在 JPA 中使多对多关系可缓存