SpringBoot Liquibase Oracle Junit test case execution fails - oracle

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.

Related

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table c_library.template_details

here is my application.properties file
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.default_schema=cLibrary
I searched my whole project but did not find c_library and still getting this error.
Earlier I was using a custom id generator later I removed it because while debugging it goes to IdentifierValueBinding class and sets schema as c_library.

how to make H2 in memory database work without having to populate the data.sql file in springboot

This might be a very simple question but I have tried to search or google how can I make it work with empty data.sql file and cant really find an answer, when you start your springboot application and you are using h2 database it always fails unless you populate the file, is there anyway to make it ignore the fact the file is empty and still be able to have an h2 database?
The following is the error you get if you have it empty:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.jdbc.datasource.init.UncategorizedScriptException: Failed to execute database script from resource [URL ["pathTo"/data.sql]]; nested exception is java.lang.IllegalArgumentException: 'script' must not be null or empty
my application properties:
spring.datasource.url=jdbc:h2:mem:citizenDB
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.defer-datasource-initialization=true
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false
Try to set property spring.sql.init.mode=never (application.yml or system env varible) in accordance with https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.data-initialization.using-basic-sql-scripts

Spring Boot datasource initialization error with data.sql script after 2.5.0 upgrade

I have a project configured with Spring Boot and Spring Data JPA.
My project contains the following data.sql initialization script (I'm just starting developing my application that's why I use an embedded H2 database):
INSERT INTO Project(id, name) VALUES (1, 'Project 1');
And I'm defining the following entity:
#Entity
public class Project {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
protected Project() {
}
public Project(String name) {
this.name = name;
}
// ...
}
I don't have any other configuration/setup in place.
ERROR 5520 ---[ restartedMain] o.s.boot.SpringApplication :Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of URL [file:/C:/path/project/target/classes/data.sql]: INSERT INTO Project(id, name) VALUES (1, 'Project 1'); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "PROJECT" not found; SQL statement:
INSERT INTO Project(id, name) VALUES (1, 'Project 1') [42102-200]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:602)
...
Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of URL [file:/C:/path/project/target/classes/data.sql]: INSERT INTO Project(id, name) VALUES (1, 'Project 1'); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "PROJECT" not found; SQL statement:
INSERT INTO Project(id, name) VALUES (1, 'Project 1') [42102-200]
at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:622)
at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.populate(ResourceDatabasePopulator.java:254)
...
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "PROJECT" not found; SQL statement:
INSERT INTO Project(id, name) VALUES (1, 'Project 1') [42102-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:453)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
Of course, before the upgrade, the application was starting just fine.
TL;DR
It seems Spring Boot has modified how it initializes the DataSource with SQL scripts with 2.5.0.
This can be fixed by including the following property in the project:
spring:
jpa:
defer-datasource-initialization: true
The explanation:
Among the changes introduced in 2.5.0, it seems now the data.sql script is executed before Hibernate is initialized:
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.5-Release-Notes#hibernate-and-datasql
And since I'm relying on the ORM mechanism (i.e. Hibernate) to create the schema from the entity definition, the database table does not exist at the moment the initialization SQL script is executed.
Add "spring.jpa.defer-datasource-initialization = true" to application.properties file.
Reason:
By default, data.sql scripts are now run before Hibernate is initialized. This aligns the behavior of basic script-based initialization with that of Flyway and Liquibase. If you want to use data.sql to populate a schema created by Hibernate, set spring.jpa.defer-datasource-initialization to true. While mixing database initialization technologies is not recommended, this will also allow you to use a schema.sql script to build upon a Hibernate-created schema before it’s populated via data.sql.
Source:
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.5-Release-Notes#hibernate-and-datasql
Hope it help somebody. I was also having the same issue, my data.sql file was not picked so only blank tables were
generating. I used below mentioned properties and it worked for me:
spring.sql.init.mode=always
spring.datasource.url= jdbc:mysql://${MYSQL_CONTAINER_NAME:localhost}:3306/${MYSQL_DATABASE:uber}
spring.datasource.username=${MYSQL_USER:boca-user}
spring.datasource.password=${MYSQL_PASSWORD:boca-password}
spring.datasource.initialization-mode=always
spring.jpa.show-sql=true
spring.jpa.defer-datasource-initialization = true
spring.jpa.hibernate.ddl-auto=update
It seems that you can make ORM vendor create the schema for you, and after that import the data by data.sql
To achieve that you also need another property: spring.sql.init.mode: always
My total set of relevant properties are the following:
spring:
sql.init.mode: always
datasource:
url: jdbc:postgresql://localhost:5432/products
username:
password:
jpa:
defer-datasource-initialization: true
hibernate:
ddl-auto: create-drop
database-platform: org.hibernate.dialect.PostgreSQLDialect
If you want to use data.sql to populate a schema created by Hibernate, set spring.jpa.defer-datasource-initialization to true.
data.sql OR schema.sql file should be save it in main/resources
Spring Boot version 2+ has a minor change. All DDL(Data Definition Language) - Table Creations and data updates should be done in schema.sql
To resolve this issue just add this, and use this because 'the data.sql or schema.sql is getting executed before our tables are created in the H2 database and we want to delay that' that's why we use this property'
spring.jpa.defer-datasource-initialization = true
to application.properties Configuration file.
or
spring:
jpa:
defer-datasource-initialization: true
Add the above if you using yml to your application.yml Configuration file.
For Example for H2 In Memory Configuration
spring.jpa.defer-datasource-initialization = true
spring.h2.console.enabled=true
spring.sql.init.platform=h2
spring.datasource.url=jdbc:h2:mem:todo
spring.datasource.username=sa
spring.datasource.password=
Sometimes I've got a SQL Syntax Error when executing the spring boot application because of forgetting the semicolon(;) at the end of CREATE TABLE and sometimes SYSDATE() and NOW() have a problem using NOW() for the current date, so make sure to write the correct SQL syntax for DDL or DML
I was facing the similar issue, I just added #Entity(name="table_name") and error got resolved.
application.properties file content:
spring.sql.init.mode=always
spring.jpa.defer-datasource-initialization = true
spring.h2.console.enabled=true
spring.sql.init.platform=h2
spring.datasource.url=jdbc:h2:mem:ToDo
spring.datasource.username=sa
spring.datasource.password=

liquibase initalization is executed in contradiction to the application.properties

Currently I have a SBA (Spring Boot App 1.5.10.RELEASE) which has two configuration property files like application-default.properties and application-oracle.properties. Furthermore those files are located in src/main/resources they end up in the resulting jar file in BOOT-INF/classes/
The applilcation-oracle.properties contains something like this:
#
# Turn off liquibase initialization.
spring.liquibase.enabled=false
# Oracle settings
spring.datasource.url=jdbc:oracle:thin:#localhost:1521/xe
spring.datasource.username=..
spring.datasource.password=...
spring.datasource.driver-class-name=...
#
# Hibernate
spring.jpa.properties.hibernate.dialect=....
#
spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
The application-default.properties looks similar except for spring.liquibase.enabled which is not contained and contains a connection to a local PostgreSQL instead of Oracle.
I have a dependency to liquibase in my pom file.
So now I would like to start my SBA simply via:
java -jar x.jar --spring.profiles.active=default ..
which prints out as expected that liquibase initialization is running..
afterwards I would like to start it like this:
java -jar x.jar --spring.profiles.active=oracle ..
and expected that the inialization via liquibase will not happen based on the given spring.liquibase.enabled=false but in contradiction to my expectation it will start the initialization via liquibase.
So the question is: Did I oversight something ?
Default properties for spring boot 1.5.10 is:
LIQUIBASE (LiquibaseProperties)
liquibase.change-log=classpath:/db/changelog/db.changelog-master.yaml # Change log configuration path.
liquibase.check-change-log-location=true # Check the change log location exists.
liquibase.contexts= # Comma-separated list of runtime contexts to use.
liquibase.default-schema= # Default database schema.
liquibase.drop-first=false # Drop the database schema first.
liquibase.enabled=true # Enable liquibase support.
liquibase.labels= # Comma-separated list of runtime labels to use.
liquibase.parameters.*= # Change log parameters.
liquibase.password= # Login password of the database to migrate.
liquibase.rollback-file= # File to which rollback SQL will be written when an update is performed.
liquibase.url= # JDBC url of the database to migrate. If not set, the primary configured data source is used.
liquibase.user= # Login user of the database to migrate.

Unable to detect database type

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

Resources