java - 使用 Spring JPA 和 H2 数据库,应用程序重新启动后 ID 不会随之变化

标签 java spring-boot hibernate jpa h2

我正在使用 Spring Boot 开发一个简单的 Web 应用程序。我使用带有嵌入式(本地)H2 数据库的 JPA。
当我启动项目时,Hibernate 会自动创建所有表和连接。效果很好。
一开始我使用h2内置控制台手动运行SQL查询进行测试。

这是我的相关文件:
pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
</dependency>

application.yml(第一次ddl-auto:创建,然后更新):

spring:
    jpa:
        open-in-view: false
        hibernate:
            ddl-auto: update
        database-platform: org.hibernate.dialect.H2Dialect
    datasource:
        driverClassName: org.h2.Driver
        url: jdbc:h2:file:~/Documents/database/blog
        username: hazazs
        password: {password}
    h2:
        console:
            enabled: true
            path: /database

博客.java

@Entity(name = "BLOGS")
public class Blog implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(nullable = false)
    private String title;
    @Column(nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date posted;
    @Column(columnDefinition = "TEXT", nullable = false)
    private String content;
    @ManyToOne
    private Blogger blogger;

Blogger.java

@Entity(name = "BLOGGERS")
public class Blogger implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(unique = true, nullable = false)
    private String email;
    @Column(nullable = false)
    private String password;
    @Column(nullable = false)
    private boolean gender;
    @Column(unique = true, nullable = false)
    private String username;
    @ManyToMany
    @JoinTable(
        name = "BLOGGERS_ROLES",
        joinColumns = {@JoinColumn(name = "BLOGGER_ID")},
        inverseJoinColumns = {@JoinColumn(name = "ROLE_ID")}
    )
    private Set<Role> roles = new HashSet<>();
    @OneToMany(mappedBy = "blogger", fetch = FetchType.EAGER)
    private Set<Blog> blogs = new HashSet<>();
    @Column(unique = true, nullable = false)
    private String code;
    @Column(nullable = false)
    private boolean enabled;

角色.java

@Entity(name = "ROLES")
public class Role implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(unique = true, nullable = false)
    private String name;
    @ManyToMany(mappedBy = "roles", fetch = FetchType.EAGER)
    private Set<Blogger> bloggers = new HashSet<>();

第一个应用程序运行时,ID 会自动递增 1。但随后我重新启动应用程序并再次连接数据库,它也会递增 1,但始终以 32 开头。
因此,如果我运行查询 INSERT INTO ROLES (NAME) VALUES ('USER')第一次在 h2 控制台中手动操作时,它会正确插入 ID 为 1 的 USER。
但是如果我运行查询 INSERT INTO ROLES (NAME) VALUES ('ADMIN')应用程序重新启动后,它会插入 ID 为 33 而不是 2 的 ADMIN。
第三次运行从 65 开始,依此类推。

到目前为止我已经尝试过(没有结果):
-第 4 代类型 @GeneratedValue
-<scope>runtime</scope>在 h2 依赖中
-数据库url:url:jdbc:h2:文件:〜/文档/数据库/博客; DB_CLOSE_ON_EXIT=FALSE

如何实现 ID 从上次应用程序运行时完成的位置继续?

最佳答案

如何重新启动应用程序?应该调用所有关闭 Hook ,并且该过程应该是正常关闭。

请参阅以下 URL 以正常关闭。

How to shutdown a Spring Boot Application in a correct way?

数据库使用 a cache of 32 entries for sequences ,而自动增量是内部实现的一个序列。如果系统崩溃而没有关闭数据库,最多会丢失这么多数字。这类似于序列在其他数据库中的工作方式。在这种情况下,不能保证生成的序列值没有间隙。

关闭所有连接将关闭数据库,如果应用程序正常停止(使用关闭钩子(Hook)),数据库也会关闭。

关于java - 使用 Spring JPA 和 H2 数据库,应用程序重新启动后 ID 不会随之变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64125581/

相关文章:

java - 为什么我无法获得矩阵元素的正确结果?

spring-boot - 我应该使用 `src/main/webapp` 通过 Spring Boot 提供静态内容吗?

java - 定义 Spring AOP 后无法切换数据库

java - oracle中使用hibernate自动增量列

使用附加列 hibernate 多对多映射?

java - 如何创建提供增删改查操作的通用 DAO,而无需通过不提供其他方法的自定义 DAO 来扩展它

java - Gradle绝对/相对路径

java - 使用 CDI 的简单 Faces Flow 中的 ContextNotActiveException

java - 保存实体后 Hibernate 一对一和多对一关系的奇怪行为

Azure Application Insights 控制台日志格式