H2 Console Cant see tables created by JAVA - java

I have downloaded the H2 console from http://www.h2database.com/html/download.html
and I have configured the URL in my jdbc.properties file
to jdbc:h2:c:/data/Messaging.
I am using the same URL in the file to connect to the database but I cannot see the tables;
I can only see the Information Schema and when I try to select * from tables in it I cannot see the tables neither.
Does anybody have any idea what could be wrong?

One tricky thing is that the H2 console will not give you an error if you try to connect to a JDBC URL that doesn't exist. It will instead create a new database at that URL! To connect to the in memory DB, use this JDBC URL (http://localhost:8080/h2-console is the default console):
jdbc:h2:mem:testdb
If you were to enter something like jdbc:h2:~/test then a test.mv file would be created under your home directory. But your application would still be using the in memory database.
The console is available if you have the h2 dependency in your pom, and also the spring developer tools dependency. If you don't have the tools dependency, then you can also see it by having the h2 dependency and adding the following to your application.properties file:
spring.h2.console.enabled=true #not needed if you have spring-boot-devtools dependency
If you want the db as a file, and not in memory, add the following to applications.properties:
spring.datasource.url=jdbc:h2:~/test_db #You will see the file in your home directory.
H2 isn't meant for persisted data, but if you want to persist for testing purposes, then add:
spring.jpa.hibernate.ddl-auto = update
Then start up the app, and at the console, use this JDBC URL:
jdbc:h2:~/test_db
In case you were wondering, I only have 1 entry in application.properties (for the database file) and here are my dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>

This is how you enable memory enable database using h2 module.
You need to ensure the following things
You had class that has #Entity annotations.
you need to enable the following in application.properties file spring.h2.console.enabled=true
Run Spring Boot and enter the following URL localhost:8080/h2-console
This will show a connection screen. Enter the following changes in the JDBC URL: -> jdbc:h2:mem:testdb
Hit the connection button.

Based on your question, it doesn't look like you fell victim to this particular pitfall, but this thread ended up helping me nail down the issue, so I am recording the solution here for posterity since it may help others with the same problem.
I also found that when I tried to open my database with the H2 console that I got what appeared to be a blank H2 database (basically, just an INFORMATION_SCHEMA table). While double-checking that I got the name of the DB correct (mydb.mv.db), I discovered that the H2 console had created a second database file, mydb.mv.db.mv.db. Odd.
It turns out that the H2 Console expects you to omit the suffix .mv.db from the filename. Since I hadn't, it was looking for mydb.mv.db.mv.db. Changing the JDBC string to jdbc:h2:mydb solved the problem and I could then open the file from the H2 Console.

Had the same Problem.
This solved it for me:
Why is my embedded h2 program writing to a .mv.db file
Just added ;MV_STORE=FALSE and ;MVCC=FALSE to the jdbc url and everything worked just fine.

I have used the below and I see my table get created.
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE
spring.h2.console.enabled=true
spring.h2.console.path=/h2console
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect

You can also avoid this problem by using the same version between H2 console and your Java code.
This is how I solved this same issue here.

Add Annotation #EntityScan("packageName") in main class

I finally figured out how to view my default in-memory H2 database tables. I'm sharing this solution because I think the process must have changed recently, due to security concerns. It is no longer possible to use the default jdbc:h2:mem:testdb to gain access to the db, nor to set a name for entry via the application.properties line spring.datasource.name=yourdbnamehere.
As of this writing, when the application starts, there is a console message similar to the following:
2021-04-26 21:16:44.424 INFO 23142 --- [ restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:6da7bb82-4008-4396-b825-09e44c17388b'
I'm using Spring Tool Suite 4. Other IDEs may format this message differently.
The key part is the last section of this string, where the database address is specified. The identifier for the database now changes with each boot. (Maybe there is a way to suppress this, but I don't know it.)
I copied the address jdbc:h2:mem:whatever-long-random-name, and pasted it into the h2-console Login Form field labeled "JDBC URL". Once in, hitting or clicking Connect will bring up the database schema and console.
The tutorial I'm working through is Dan Vega's "Springit" application, from his Getting Started With Spring Boot 2.0 course. I'm including this info as a search breadcrumb for anyone following. This course may be a couple years old now, but Vega does a much better-than-average job of explaining, so it remains worthwhile. However, tech marches on, and I assume the need for enhanced security has grown to the point where it's no longer safe to allow an easily guessable database name.

Related

Unable to get database credentials from AWS parameter store in time to make DB connection after Spring Boot upgrade to 2.7.2

I recently upgraded a Spring Boot microservice from v2.6.7 to v2.7.2. In the code, we retrieve database credentials from an AWS parameter store and use them to connect to a Postgres database. We take param values that indicate what to retrieve from the AWS parameter store, retrieve those values and and then add those values to the Spring environment (as spring.datasource.username & spring.datasource.password).
This was working without issue before we upgraded to 2.7.2. However, since the upgrade, we seem to have a timing issue where a database connection is attempted before the values have been retrieved. We don't even reach the code to do the parameter store retrieval before it tries to make the DB connection. However, in my properties file, if I put valid values in the hardcoded parameters below (& uncomment them), the database connection is made and I see the code to go get the AWS parameter store values run, so I know the code is good. The class that does the work of getting the values is #Autowired in my SpringBootApplication class.
spring.datasource.url=jdbc:postgresql://<aws URL>
spring.datasource.username.param=<aws parameter store for username>
spring.datasource.password.param=<aws parameter store for password>
# spring.datasource.username=<a valid hardcoded username>
# spring.datasource.password=<a valid hardcoded pwd>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-bom</artifactId>
<version>1.12.301</version>
<type>pom</type>
</dependency>
Did anything change in the latest Spring Boot version that would affect the nature &/or order of the auto wiring? How can I force the database connection attempt to wait until the DB creds have been retrieved? Any troubleshooting suggestions?

Unable to make JDBC Connection ["jdbc:mysql://localhost:3306/practiceDB"]

I am new to hibernate. While running my first program I am facing 2 errors.
Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] and
Unable to make JDBC Connection ["jdbc:mysql://localhost:3306/practiceDB"]
Dependencies in pom.xml
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.8.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
JAVA code
Configuration cfg=new Configuration();
cfg.configure();
SessionFactory factory=cfg.buildSessionFactory();
System.out.println(factory);
By default, Hibernate uses its internal database connection pool library. That means it keeps a database connection open to be reused later. And MySQL database server has a timeout value for each connection (default is 8 hours or 28,800 seconds). So if a connection has been idle longer than this timeout value, it will be dropped by the server.
Therefore, when the Java database application has been idle longer than MySQL server’s connection timeout value, and the end user tries to connect again, Hibernate reuses the idle connection which was already dropped by the server, hence JDBCConnectionExceptionis thrown.
Expiring and/or testing connection validity before use in your application:
This requires changing or re-structuring the existing code, which is difficult to implement. Furthermore, opening a database connection is an expensive operation so it’s not optimal to open and close database connection for every user’s request - that’s why database connection pooling comes into play.
EDIT
As #Reg mentioned in a comment below my post, the following approach is only applicable when also using the spring-boot-starter-data-jpa dependency, so if you are not bound to use hibernate directly, feel free to include the dependency and follow the approach down below.
Also, a guide that is worth reading that also helped me a lot Introduction to Spring Data JPA
When using Spring you don't always need to write a configuration class for your database connection (atleast if you only have one single datasource).
You can simply configure your datasource via your application.properties or application.yaml file.
Try adding this to your application.properties file:
spring.datasource.url=jdbc:mysql://localhost:3306/practiceDB
spring.datasource.username=yourUsername
spring.datasource.password=yourPassword
Or adding this to your application.yaml file:
spring:
datasource:
url: jdbc:mysql://localhost:3306/practiceDB
username: yourUsername
password: yourPassword
This should allow you to establish a connection to your datasource.

Generating sample database data via Spring data.sql file

I would like to initialize my postgres database with data.sql file. I have created queries like:
insert into network_hashrate (
rep_date, hashrate
)
select
date_from - (s.a || ' hour')::interval,
s.a::double precision
from generate_series(0, 9999, 1) AS s(a);
Is it even possible to populate database using postgres functions in Spring? If not, what are my other options. I need like 10k sample records.
According to Spring Boot doc:
Spring Boot can automatically create the schema (DDL scripts) of your DataSource and initialize it (DML scripts). It loads SQL from the standard root classpath locations: schema.sql and data.sql, respectively.
So if you need to populate data only - just create data.sql file with your sql-scripts, place it to resources folder, then check spring.jpa.hibernate.ddl-auto in the application.properties to be set to none.
If you need more flexible solution, you can use Flyway. To use it - add its dependency to your project
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
Turn the spring.jpa.hibernate.ddl-auto to validate.
Add spring.flyway.enabled=true to application.properties.
Place you 'migration' sql scripts to the 'default' location resources/db/migration folder. Call them like this, for example:
V1__schema_initialization.sql
V2__data_population.sql
When your spring boot app will be starting, Flyway check your database for missing schema and data then rolls these scripts sequentially.
More info about Flyway is here.
Seems you can run sql script after db scheme validate/created
Just name sql query file import.sql and spring should run it according this doc
You need something that will keep a track of what query ran and when ran. Also it should only run once not all the time when application startups.
liquibase is a option which can be used for that.
It will allow DDL as well as DML.
This link will give detail, How can you configure liquibase with spring
https://medium.com/#harittweets/evolving-your-database-using-spring-boot-and-liquibase-844fcd7931da

Visualizing an embedded H2 database

I'm trying to configure and use a H2 embedded DB with Spring Boot. I'm using the code provided in the doc:
#Bean
public DataSource dataSource() {
return new EmbeddedDatabase db = new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
// .addScript("schema.sql") Omit, auto-generate
.build();
}
The application works fine, I can create and retrieve data, but I would like to visually see it. I've installed the H2 Console Application, but I'm not sure how to connect to the in-memory instance. I go to http://localhost:8082 and then, under JDBC URL I input when I get from the connection's metadata (I've tried with auto-generated and manually specified names), but the H2 Console Application seems to be connected to an empty schema. My tables don't appear there, only the information schema, and I can't SELECT from my tables either, they just don't exist here.
What's going on, what DB am I connecting to? How can I connect to my embedded DB?
If you want to see your tables on h2 console in your application, you don't need to install "Console Application". You just need to enable to see visually and also set your datasource url in application.properties . It seems like that:
spring.datasource.url=jdbc:h2:mem:nprensen;(or if you have already a ds you should write that url)
spring.h2.console.enabled=true
spring.h2.console.path=/console // this is the path for h2 console:localhost:8080/console
Please add the following dependency you can serve http requests. In that way, you can send a http request to access h2 console from your browser.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>

How to see all tables in my h2 database at localhost:8082?

I use JDBC and created h2 database called usaDB from sql script. Then I filled all tables with jdbc.
The problem is that after I connect to usaDB at localhost:8082 I cannot see on the left tree
my tables. There is only INFORMATION_SCHEMA database and rootUser which I specified creating usaDB.
How to view the content of tables in my h2 database?
I tried query SELECT * FROM INFORMATION_SCHEMA.TABLES.
But it returned many table names except those I created. My snapshot:
I had the same issue and the answer seems to be really stupid: when you type your database name you shouldn't add ".h2.db" suffix, for example, if you have db file "D:\somebase.h2.db" your connection string should be like "jdbc:h2:file:/D:/somebase". In other way jdbc creates new empty database file named "somebase.h2.db.h2.db" and you see what you see: only system tables.
You can use the SHOW command:
Using this command, you can lists the schemas, tables, or the columns of a table. e.g.:
SHOW TABLES
This problem drove me around the twist and besides this page I read many (many!) others until I solved it.
My Use Case was to see how a SpringBatch project created in STS using :: Spring Boot :: (v1.3.1.RELEASE) was going to behave with the H2 database; to do the latter, I needed to be able to get the H2 console running as well to query the DB results of the batch run.
This is what I did and found out:
Created an Web project in STS using Spring Boot:
Added the following to the pom.xml of the latter:
Added a Spring configuration file as follows to the project:
This solves the Web project deficiencies in STS. If you run the project now, you can access the H2 console as follows: http://localhost:8080/console
Now create a SpringBatch project in STS as follows (the alternative method creates a different template missing most of the classes for persisting data. This method creates 2 projects: one Complete, and the other an initial. Use the Complete in the following.):
The SpringBatch project created with STS uses an in memory H2 database that it CLOSES once the application run ends; once you run it, you can see this in the logging output.
So what we need is to create a new DataSource that overrides the default that ships with the project (if you are interested, just have a look at the log messages and you will see that it uses a default datasource...this is created from:
o.s.j.d.e.EmbeddedDatabaseFactory with the following parameters:
Starting embedded database: url='jdbc:hsqldb:mem:testdb', username='sa')
So, it starts an in memory, and then closes it. You have no chance of seeing the data with the H2 console; it has come and gone.
So, create a DataSource as follows:
You can of course use a properties file to map the parameters, and profiles for different DataSource instances...but I digress.
Now, make sure you set the bit that the red arrow in the picture is pointing to, to a location on your computer where a file can be persisted.
Running the SpringBatch (Complete project) you should now have a db file in that location after it runs (persisting Person data)
Run the Web project you configured previously in these steps, and you WILL :=) see your data, and all the Batch job and step run data (et voila!):
Painful but rewarding. Hope it helps you to really BOOTSTRAP :=)
I have met exactly this problem.
From what you describe, I suppose that you connect your jdbc with the "real" h2 server, but you are connecting on web application to database by the wrong mode (embedded-in-memory mode, aka h2mem). It means that h2 will create a new database in-memory, instead of using your true database stored elsewhere.
Please make sure that when you connect to this database, you use the mode Generic H2 (Server), NOTGeneric H2 (Embedded). You can refer to the picture below.
Version of jar file and installed h2 database should be same.
If in case you have created and populated H2 database table using maven dependency in spring boot, then please do change the JDBC URL as jdbc:h2:mem:testdb while connecting to H2 using web console.
It is an old question, but I came across the same problem. Eventually I found out that the default JDBC URL is pointing a test server rather than my application. After correcting it, I could access the right DB.
I tried with both Generic H2 (Embedded) and the Generic H2 (Server) options, both worked as long as the JDBC URL: is provided correctly.
In grails 4.0.1 the jdbc URL for development is jdbc:h2:mem:devDb. Check your application.yml file for the exact URL.
For the people who are using H2 in embedded(persistent mode) and want to "connect" to it from IntelliJ(other IDEs probably apply too).
Using for example jdbc url as follows: jdbc:h2:./database.h2
Note, that H2 does not allow implicit relative paths, and requires adding explicit ./
Relative paths are relative to current workdir
When you run your application, your workdir is most likely set to your project's root dir
On the other hand, IDE's workdir is most likely not your project's root
Hence, in IDE when "connecting" to your database you need to use absolute path like: jdbc:h2:/Users/me/projects/MyAwesomeProject/database.h2
For some reason IntelliJ by default also adds ;MV_STORE=false. It disables MVStore engine which in fact is currently used by default in H2.
So make sure that both your application and your IDE use the same store engine, as MVStore and PageStore have different file layouts.
Note that you cannot "connect" to your database if your application is using it because of locking. The other way around applies too.
In my case the issue was caused by the fact that I didn't set the h2 username, password in java. Unfortunatelly, Spring didn't display any errors to me, so it was not easy to figure out. Adding this lines to dataSource method helped me fix the issue:
dataSource.setUsername("sa");
dataSource.setPassword("");
Also, I should have specified the schema when creating tables in schema.sql
Selecting Generic H2 (Server) solved for me. We tempted to use default Generic H2 (Embedded) which is wrong.

Categories