H2 not creating/updating table in my Spring Boot app. Something's wrong with my Entity?
Just go to the H2 console for example at: http://localhost:9090/h2-console/ and In the JDBC URL field, type jdbc:h2:mem:testdb to configure the connection to the testdb database in RAM.
It looks like data is binded to parameters, but in H2 console SELECT * FROM GAME returns me nothing. The table doesn't exist.
You are using an in-memory
instance of H2 :
spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
In this mode, you cannot see the content of the changes from another client that which one that started the in-memory
database.
To see the changes from other clients, you have to use the TCP mode.
You have two solutions :
- using a file to persist the instance of H2.
Where are the Database Files Stored?
When using database URLs like jdbc:h2:~/test, the database is stored in the user directory. For Windows, this is usually C:\Documents and Settings\ or C:\Users\. If the base directory is not set (as in jdbc:h2:./test), the database files are stored in the directory where the application is started (the current working directory). When using the H2 Console application from the start menu, this is /bin. The base directory can be set in the database URL. A fixed or relative path can be used. When using the URL jdbc:h2:file:./data/sample, the database is stored in the directory data (relative to the current working directory). The directory is created automatically if it does not yet exist. It is also possible to use the fully qualified directory name (and for Windows, drive name). Example: jdbc:h2:file:C:/data/test
- keeping to use an in-memory instance but using the TCP mode.
Replace :
spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
by :
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
Generally, I switch to this mode during JPA entity unit testing when I really want to know which was inserted in the database.
From the official documentation :
In-Memory Databases
For certain use cases (for example: rapid prototyping, testing, high performance operations, read-only databases), it may not be required to persist data, or persist changes to the data. This database supports the in-memory mode, where the data is not persisted. ...
In some cases, only one connection to a in-memory database is required. This means the database to be opened is private. In this case, the database URL is jdbc:h2:mem: Opening two connections within the same virtual machine means opening two different (private) databases.
Sometimes multiple connections to the same in-memory database are required. In this case, the database URL must include a name. Example: jdbc:h2:mem:db1. Accessing the same database using this URL only works within the same virtual machine and class loader environment.
To access an in-memory database from another process or from another computer, you need to start a TCP server in the same process as the in-memory database was created. The other processes then need to access the database over TCP/IP or TLS, using a database URL such as: jdbc:h2:tcp://localhost/mem:db1.
Alternative to standalone H2 Console : using the H2 console accessible from the Spring Boot application
Indeed the H2 database provides a browser-based console that Spring Boot can auto-configure for you. The console is auto-configured when these conditions are met :
- You are developing a servlet-based web application.
- com.h2database:h2 is on the classpath.
- You are using Spring Boot’s developer tools.
So it means that will be accessible only in dev. What generally you want.
By default, the console is available at /h2-console
.
Set the spring.h2.console.path
property to change that.
Check if you main class(Spring boot application class) is able to scan the entities defined. This usually happens when the entities are in a different package than that of the main class.