1

I'm working on a simple webapplication with Spring Boot. I use JPA with embedded (local) H2 database.
When I start the project, Hibernate makes all the tables and connection automatically. It works fine.
In the beginning I use the h2 built-in console to run SQL queries manually for testing.

Here are my related files:
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 (First time ddl-auto: create, then update):

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

Blog.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;

Role.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<>();

With the first application run the ID increments automatically by 1. But then I restart my application and connect the database again, however it increments by 1 as well, but it starts with 32 all the time.
So if I run the query INSERT INTO ROLES (NAME) VALUES ('USER') first time manually in the h2 console, it inserts USER with ID 1 correctly.
But if I run the query INSERT INTO ROLES (NAME) VALUES ('ADMIN') after the application restart, it inserts ADMIN with ID 33 instead of 2.
The third run starts with 65 and so on.

I have tried so far (with no result):
-the 4 GenerationType for @GeneratedValue
-<scope>runtime</scope> in the h2 dependency
-database url: url: jdbc:h2:file:~/Documents/database/blog;DB_CLOSE_ON_EXIT=FALSE

How could I achieve, that the ID continues from where it finished at the previous application run?

tibotka
  • 145
  • 10

1 Answers1

3

How do you restart the app? All the shutdown hooks should be called and the process should be a graceful shutdown.

Refer below URL for graceful shutdown.

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

The database uses a cache of 32 entries for sequences, and auto-increment is internally implemented a sequence. If the system crashes without closing the database, at most this many numbers are lost. This is similar to how sequences work in other databases. Sequence values are not guaranteed to be generated without gaps in such cases.

Closing all connections will close the database, and the database is closed if the application is stopped normally (using a shutdown hook).

Alien
  • 11,017
  • 3
  • 29
  • 45
  • With "Stop the currently executing build" button via NetBeans. So due to the cache there isn't any solution for this (except from not shutting down the app)? – tibotka Sep 29 '20 at 19:11
  • 1
    Yes....so basically what is happening is, the shutdown is not making database connection closed. – Alien Sep 29 '20 at 19:13
  • Then "sadly" I mark your response as answer. Thanks for the clarification. – tibotka Sep 29 '20 at 19:32