Unable to detect database type - spring-boot

I'm trying to create a Spring Boot application using sqljdbc4 driver with this config:
spring:
datasource:
url: "jdbc:sqlserver://dbhost:1433;databaseName=test"
username: dbuser
password: dbuser
tomcat:
test-on-borrow: true
validation-query: select 1
But, when I run, I get this error: Unable to detect database type
I was debugging BatchDatabaseInitializer, where error came from, and when it calls JdbcUtils.commonDatabaseName(...), "Microsoft SQL Server" is returned as product name that doesn't match with any DatabaseDriver's product name.
I tried other drivers but they all have the same problem.
Is it a bug?
I'm using Spring Boot 1.5.1-RELEASE.

You need to properly configure your spring.datasource config in application.properties file if you're using spring-batch to create batch jobs. Below is mine ->
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/batch_repo
spring.datasource.username=batch_username
spring.datasource.password=batch_password
spring.datasource.platform=mysql
spring.batch.initialize-schema=always
spring.batch.initialize-schema when configured to "always", will create the necessary spring batch related tables in your schema.
Alternatively, if you assign it to "never", it will refrain from creating the tables. In both these cases your error should get resolved.

Try spring.batch.jdbc.initialize-schema=never in props file. It worked for me in spring-boot v2.6.x

Add this in your Application file within the main function.
#SpringBootApplication(
exclude = {
BatchAutoConfiguration.class,
JmxAutoConfiguration.class
},
excludeName = {
"org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration",
}
)

Put this in your application.properties.
spring.batch.schema=classpath:org/springframework/batch/core/schema-sqlserver.sql

Check your application.properties file like below.
Note: springbatch is my DB name
spring.datasource.url=jdbc:mysql://localhost:3306/springbatch
spring.datasource.username=root
spring.datasource.password=Vishal#123
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.batch.jdbc.initialize-schema=always

Related

SpringBoot Liquibase Oracle Junit test case execution fails

I have a SpringBoot application in which i use Liquibase to generate oracle schema and tables.
When i run the application, it runs fine.
But when i try to run the Junit test case, it fails with below error,
Error creating bean name 'liquibase' defined in class path resource....
Migration failed for change set /db/changelog/....
Reason : liquibase.exception.DatabaseException: Schema "XYZ" not found; SQL statement
The schema and tables are all present in the Database.
Still, why do i get this error?
Any suggestions please.
I found an article on Medium regarding the Schema Not Found part of your error. Link: Fix - Schema Not Found and Why
In step 3, the article recommends spring users add a file in your resource folder and name it schema-h2.sql. Within the file they give this example:
-- CREATE DATABASE IF NOT EXISTS
CREATE SCHEMA IF NOT EXISTS testdb;
For step 4, you turn on your initialization-mode in your *.properties files. This will cause the schema-platform.sql files to be executed as expected.
spring.datasource.initialization-mode=embedded
When you reach step 5, make sure your platform name matches the *.sql file. the example they show in the screenshot in the article is shown below.
# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
#spring.datasource.hikari.maximumPoolSize=8
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;DB_CLOSE_ON_EXIT=FALSE;
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.platform=h2
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.datasource.name=testdb
Then, double check all your schema names match perfectly, and you should be good to go.

getting Could not resolve placeholder while reading yml values in spring boot

I'm using spring boot and using this value in my application.yml
config:
username: abc
password: xyz
In my class, I'm utilizing it this way -
#Value("${config.username}")
private String username;
I'm getting the following error -
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'config.username' in value "${config.username}"
However if I use this in my application.yml file, it works. Can you please tell me what I'm doing wrong here?
config.username: abc
config.password: xyz
check your placeholder is Tab or Space ? make sure no Tab in your yml file.
was facing the same problem when trying to read from application.yml file instead of application.properties file. maven clean & then maven install resolved the issue for me.

springboot 2.3.0 while connecting to h2 database

In Springboot 2.3.0.RELEASE
I am getting the the following error while connecting to h2 database in the console
Database "mem:testdb" not found, either pre-create it or allow remote
database creation (not recommended in secure environments) [90149-200]
90149/90149
You can fix this by setting the spring.datasource.url property like so:
spring.datasource.url=jdbc:h2:mem:testdb
Prior to Spring Boot 2.3.0-RELEASE this was the default, but I'm not sure where it's set. As of 2.3.0-RELEASE, the schema looks to be a randomly generated GUID.
Step 1. In application.properties:
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
Step 2. Start your Spring Boot App and open:
http://localhost:8080/h2-console/
If you still face issue try pasting the URL value which you mentioned in application.properties jdbc:h2:mem:testdb in
JDBC URL of h2-console
Then you wont face below mentioned issue
Database h2 not found, either pre-create it or allow remote database creation (not recommended in secure environments) [90149-200] 90149/90149 (Help)
Actually, your h2 databse is looking for a file called test.mv.db. But
that file was not present in your user directory. So, that it just
slapping you and asking you to pre-create it in that path.
Note: That is the root file where our H2 DB store all our information.
Add below line in your application.properties file
spring.datasource.url = jdbc:h2:mem:testdb
Go to your user directory, in my case, it is (C:\Users\subra)
Create a new file called test.mv.db and saved it under all file option like below.
Now restart your app.
Done
Reference Screenshot:
My Problem:
The Result
You are not able to connect to database because you are using old JDBC URL. Every time you start a spring project, JDBC URL changes as well.
Solution: Copy the JDBC URL from console every time you want to connect to a database or just use below property in application.properties file
spring.datasource.url=jdbc:h2:mem:testdb
Another reason for the error could be a the missing JDBC dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
I got the exact same error and this was the issue in my case.
In Spring Boot 2.3.0 the property spring.datasource.generate-unique-name is set to true. This enables the random generation of the schema name.
By setting it to false the database is generated as in previous versions (jdbc:h2:mem:testdb). I find this way preferable, without the need to specify the URL manually.
Create a file with a .mv.db extension in your project's folder. Make sure that the file's name ends with .mv.db otherwise H2 console does not recognize the file (I know it doesn't make sense and I have no explanation why :D). After creating the file, enter jdbc:h2:./devdb to h2 console's JDBC URL like this:
Then you should be OK!
Step 1. Download h2 database engine from here:
https://www.h2database.com/html/main.html
Step 2. In application.properties:
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
Step 3. Start your Spring Boot App and open:
http://localhost:8080/h2-console/
It must be working fine for you.
Use h2 dependency with the old version (1.4.192).
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.192</version>
<scope>runtime</scope>
</dependency>
I added "test.mv.db" file into "C:\Users\YourUserName" then restart the server and it's worked.
Since 2.3.0, default value of generate-unique-name is true.
You can revert to the previous behavior by following setting:
spring.datasource.generate-unique-name=false
see also: https://stackoverflow.com/a/62750194/4506703
Even I came across the same set of errors when started learning data persistence with h2 database. The solution is in the console log itself. The database name is auto-generated by and can be found in the spring logs. The reason behind the error is after from 2.3.0 version release onwards if the URL is not mentioned its auto-generated.
Here is the log message which includes database URL:
INFO 16096 --- [ restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:f1dfeade-60dd-4809-8978-42547353b2f3'
Add property to application.properties:
spring.datasource.generate-unique-name=false
I had also missed adding the following dependencies to pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
In case this helps anybody. My issue was because I have this in my application.properties
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
Not sure why I added this config before. But once this is taken out, it solves my issue
Adding Spring-boot started JDBC solved my issue.
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc/2.5.2
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>2.5.2</version>
</dependency>
I had the same problem and I got it solved this way
Go to application.properties
Add the following :
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
now you can use sa for username and password for password
PS : that's usually the by default configuration that spring boot uses
It's error of H2-Database:
Solution -
Let's suppose ~/Test-H-2/Project-X/DB-files path of your project (Database files)
create myTest.mv.db file in ~/Test-H-2/Project-X/DB-files folder
Add jdbc:h2:~/Test-H-2/Project-X/DB-files/myTest to JDBC URL in H2-Database console
OR
simply you can create ~\test.mv.db file & add jdbc:h2:~/test in to JDBC URL in H2-Database console
i had the same problem while creating schema for h2 database in spring version 2.3.0 ...sometimes the database would connect but could not show me my structure of table so i tried chaneging the spring version and it worked like an magic try changeing spring version to 2.1.15.RELEASAE
I had same issue in windows 10. Try to replace
spring.datasource.url=jdbc:h2:~/testdb
with
spring.datasource.url=jdbc:h2:mem:testdb
Replace the default JDBC url of h2-console from application.properties to use JDBC Url=jdbc:h2:mem:testdb
Below is the application.properties
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=user
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
Add these two properties in application.property file
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
type url: localhost:<portnumber>/h2-console in browser
You will get a page regrading login database
Remove existing JDBC url in the page and put this jdbc:h2:mem:testdb
I connect h2 by jdbc:h2:mem:testdb but not jdbc:h2:~/testdb
my solution for this problem is:
in case you you didn't made a database folder in home directory (in windows under the: C:\Users*USERNAME\test* || in Linux: under the: ~/test) make it and add below lines to application.properties:
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:h2:~/test
spring.jpa.hibernate.ddl-auto=create-drop
it should help you to login.
((use blank username and password for H2))
Adding to answers, which mention auto-generated database name in Spring Boot 2.3+ – this is the way how to get the generated name into H2 Console programatically in Spring Boot, so that you can keep the generated database name. It basically gets the first H2 database source and updates/generates the H2 Console configuration file ~/.h2.server.properties, which is then loaded by H2 Console when it is first accessed.
Configure pom.xml to use H2 types directly:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>compile</scope>
</dependency>
Enable H2 Console in application.properties (true is a default value):
spring.h2.console.enabled=true
Code to use auto-generated database name:
import java.io.OutputStream;
import java.sql.Connection;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.h2.engine.Constants;
import org.h2.store.fs.FileUtils;
import org.h2.util.SortedProperties;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Configuration;
#Configuration
#AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class H2ConsoleDatabaseAutoConfigurator {
#Autowired
public void configure(ObjectProvider<DataSource> dataSource) throws Exception
{
Properties properties = SortedProperties.loadProperties(Constants.SERVER_PROPERTIES_DIR + "/" + Constants.SERVER_PROPERTIES_NAME);
List<String> urls = dataSource.orderedStream().map((available) -> {
try (Connection connection = available.getConnection()) {
if (connection.getMetaData().getURL().startsWith("jdbc:h2:mem:")) {
return connection.getMetaData().getURL() + "|" + connection.getMetaData().getUserName();
} else {
return null;
}
}
catch (Exception ex) {
return null;
}
}).filter(Objects::nonNull).collect(Collectors.toList());
if (urls.size() > 0)
{
for (int i = 0;; i++)
{
String value = properties.getProperty(String.valueOf(i), null);
if (value == null || value.startsWith("Local H2|")) {
properties.setProperty(String.valueOf(i), "Local H2|org.h2.Driver|" + urls.get(0));
break;
}
}
OutputStream out = FileUtils.newOutputStream(
Constants.SERVER_PROPERTIES_DIR + "/" + Constants.SERVER_PROPERTIES_NAME, false);
properties.store(out, "H2 Server Properties");
out.close();
}
}
}
The console will contain the current H2 name as Local H2 menu entry:
The code is a composite of sources from H2 Console and Spring Boot H2 Console Autoconfiguration.
NOTE:->spring.datasource.url=jdbc:h2:mem:nilesh-->Should be same in console(JDBC URL)
application.properties
spring.h2.console.enabled=true
spring.datasource.platform=h2
spring.datasource.url=jdbc:h2:mem:nilesh
Adding JPA Dependency to pom.xml fixed this error for me.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Here is my application.properties file, just for your reference.
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testapp
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
I am using Spring 2.7.3.
I had the same issue with mem:testdb not found. After trying out all the different solutions I could find in Stackoverflow, the only solution that worked for me was adding both "spring.datasource.url=jdbc:h2:mem:testdb" AND "spring.datasource.generate-unique-name=false" in my application properties file.
I thought that by adding just the "spring.datasource.url=jdbc:h2:mem:testdb" should stop spring from generating unique name everytime I restart the application but apparently not. Manually creating the test.mv file did not work for me either. Hope this helps.
Looks like everybody trying their own ways but solution to problem is NOT configuration but PHYSICAL.
See #Subramanian answer.
Somehow , If you want to connect via console, Spring is unable to create a PHYSICAL file testdb.mv.db in root folder, i.e C:/USERS/testdb.mv.db.
I went to C:/Users/SHEKHAR , and created a New > text file ( don't save it untill you rename it to testdb.mv.db or .mv.db.
Restart Springboot, "Test Connection" is Green and Connect , takes me to Console GUI.
Remove the spring-boot-devtools dependency from pom.xml and restart the application. for me, this worked.
Please use this below solution it's working.
If you are dealing with the Spring Boot project, please change the JDBC URL jdbc:h2:~/test to jdbc:h2:mem:testdb in the login page, which is the default URL configured by Spring Boot.

"java.lang.IllegalStateException: Cannot load driver class" in Spring Boot application

I am using to configure spring boot with an external YAML configuration and CMD.
-> application.yml file
spring:
profiles: integration-test
datasource:
driverClassName: ${SPRING_DATASOURCE_DRIVER_CLASS_NAME}
url: ${SPRING_DATASOURCE_URL}
username: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}
-> cmd
mvn clean install
-> Result
Caused by: java.lang.IllegalStateException: Cannot load driver class: ${SPRING_DATASOURCE_DRIVER_CLASS_NAME}
Can anyone explain this to me?
When you use the syntax ${}, you are actually telling Spring Boot to use the value of the property whose name is between brackets. In your case, Spring Boot tries to resolve the property SPRING_DATASOURCE_DRIVER_CLASS_NAME. When it fails, it uses the string as is, which leads to the error you mentioned, since no driver exists under the name ${SPRING_DATASOURCE_DRIVER_CLASS_NAME}.
To solve the issue, you can either :
replace the ${} by the real values, e.g. driverClassName: org.postgresql.Driver and do the same for the other properties (url, username and password)
provide properties SPRING_DATASOURCE_DRIVER_CLASS_NAME,SPRING_DATASOURCE_URL and the two others. These can passed in the command line with -D options (e.g. -DSPRING_DATASOURCE_DRIVER_CLASS_NAME=org.postgresql.Driver) or through environment variables. You can look at spring Boot documentation for more details.
Pass those variables in your launch configuration of your program or at commandline when you run your app with java YourMainClass, e.g.
java -DSPRING_DATASOURCE_DRIVER_CLASS_NAME=<full_qualified_name_of_your_jdbc_driver_class> -DSPRING_DATASOURCE_URL=<jdbc_url> YourMainClass
also pass the other two variables the same way, username & password!
your can even set those enviroment variables on OS level, so you don't have to set them each time you start your application...
if your using Spring Boot also have a look at this one: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

H2 Database not found error: 90146. H2 database is not created on start

Just created a simple spring-boot project from the spring initializer. I went to add a local h2 db for testing and am unable to login. Seems that it cannot create the test db when starting up but cannot figure out why this may be the case.
spring:
h2:
console:
enabled: true
path: /h2
datasource:
url: jdbc:h2:mem:testdb;
username: sa
password:
driver-class-name: org.h2.Driver
platform: h2
jpa:
show-sql: true
hibernate:
ddl-auto: create
properties:
hibernate:
dialect=org:
hibernate:
dialect:
H2Dialect: org.hibernate.dialect.H2Dialect
Database "mem:testdb" not found, and IFEXISTS=true, so we cant auto-create it [90146-199] 90146/90146
In earlier version of spring, default url will be jdbc:h2:mem:testdb and testdb was created by default. from 2.3.0 onwards, if url is not mentioned it will auto generate database name. auto generated database name can be found in the spring logs.
I had the same error and I found these to be helpful:
Adding a pre-2019 version to the pom.xml file as below:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.193</version>
</dependency>
This fixes the error but isn't the right way to do it. The newer version of H2 Database do not create a new database as it doesn't exist by default and are enabled to false for security purposes.
A better way would be adding making changes to url as:
jdbc:h2:mem:testdb;IFEXISTS=FALSE;
Hope it helps. I made changes in my application.properties file.
just append this to your application.properties file.
spring.datasource.url=jdbc:h2:mem:testdb
spring.data.jpa.repositories.bootstrap-mode=default
As Stuck said.
Simply remove the semicolon:
wrong: jdbc:h2:mem:testdb;
correct: jdbc:h2:mem:testdb
I have the same problem with windows. I just change spring.datasource.url in application property file to jdbc:h2:file:C:/data/sample and run project. after that set JDBC URL to jdbc:h2:file:C:/data/sample. look like picture
JDBC URL
I had a same problem and I changed the version of Spring Boot to 2.1.3 and it works
wrong:
spring.datasource.url=jdbc:h2:mem:testdb
This below solution worked for me
spring.datasource.url=jdbc:h2:file:~/test;
If you are using spring boot in order to use h2 DB, make sure you have dependencies on your pom.xml file
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
Your application.yml makes it possible to access h2 DB by URI /h2-console preceded by server URL and to connect to DB named "testdb" with username "sa" and no password, after the application has been started on the server.
maybe you have to setting about h2.
In application.properties
spring.h2.console.enabled=true
spring.h2.console.settings.web-allow-others=true
spring.datasource.generate-unique-name = false
spring.h2.console.path=/h2-console
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
when you put these codes in Application.properties you can see how it work!

Resources