Spring Boot Enable Specific Embedded Database HSQL over Derby - java

I'm trying to deploy My application on weblogic server, My application has an in-memory DB and since I use HSQLDB for JUNIT, I want to keep HSQL as my in-memory DB(primarily a slight better performance over derby). Since weblogic has already derby, when I try to deploy the application, The derby is getting started rather than HSQL. On Preliminary investigation I find that Since Derby is define above HSQL in EmbeddedDatabaseConnection.java, Derby database is being started first. Is there any specific configuration, where I can explicitly embedded database type to HSQL rather than allowing spring boot to start database based on library/classes

First try I can think of is to remove Derby from class path and leave there only HSQL. Spring Boot docs:
If HSQLDB is on your classpath, and you have not manually configured
any database connection beans, then we will auto-configure an
in-memory database.
If that's not an option, you can specify
connection type for Hibernate (JPA):
An embedded database is detected by looking at the Connection type: hsqldb, h2 and derby are embedded, the rest are not.
HSQL explicitly as primary data source:
#Configuration
public class DataSourceConfig {
#Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.build();
}
}
define spring.datasource.type property

Related

Flyway & Hibernate : Cannot populate data to initial database

In a Spring Boot app, I am using Hibernate and 2 tables is created properly. However, I also need to insert data one of these tables and for this purpose I thought I should use Flyway.
Then I just added insert clauses to the Flyway and use the following parameters for Hibernate and Flyway in application.properties:v
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto= update # also tried none
spring.flyway.url=jdbc:mysql://localhost:3306
spring.flyway.schemas=demo-db
spring.flyway.user=root
spring.flyway.password=******
I have not used Flyway for initializing database and I am not sure if I can use Flyway with Hibernate as I mentioned above. Or, should I disable Hibernate table creation and create another migration script for table creation?
If you use flyway only for insert data don't do that. Try to use this:
With Hibernate:
In addition, a file named import.sql in the root of the classpath is executed on startup if Hibernate creates the schema from scratch (that is, if the ddl-auto property is set to create or create-drop).
With Basic SQL Scripts:
Spring Boot can automatically create the schema (DDL scripts) of your JDBC DataSource or R2DBC ConnectionFactory and initialize it (DML scripts). It loads SQL from the standard root classpath locations: schema.sql and data.sql
The issue here is that Hibernate does not automatically create tables. Additionally, if using Spring Boot, Flyway will run before the service using hibernate has started. As a result, your Flyway script are interacting with a table that does not exist.
The recommended way to do this is to use Flyway to manage both your database structure, your create tables etc, and static data. This will mean your database is versioned and provisioned ready for your service and hibernate can connect.

Difference between connecting to a database using DriverManager and SpringBoot(Hibernate)

There are 2 ways to connect to a database when developing Java apps.
Using DriverManager
Connection conn = DriverManager.getConnection(url, name, password);
// execute the query.
Using application property file in SpringBoot
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:mysql://localhost:5432/db_name
spring.datasource.username=user
spring.datasource.password=password
Now you can use #Entity annotation on your class to put data into database.
My question is how are these 2 ways different. If not how, is SpringBoot method working same as DriverManager in the background.
I assume that by Driver Manager you wanted to made reference to JDBC and by Springboot(Hibernate) you wanted to say JPA.
To simply answer your question, both JDBC and JPA will connect to the driver. Just that if you use JPA this step is made by default without you explicitly coding it.
You can look at JPA as an upper layer of JDBC which handles all the boilerplate code like connecting to the driver.
You can read more about JPA and JDBC here: JPA or JDBC, how are they different?
When you set configuration properties you are just saying to spring: "Hey, i have this properties, can you autoconfigure what i need?". At this point spring at the start of application will use you configuration properties to setup everything you need to connect to your database (using DriverManager or not is not important).
Spring do exactly what you should to do to configure your database connection.
Remember that in 99% of cases you can't write better code than spring do. So, use spring properties

Spring Boot - Get rid of Hikari Data Source and use H2

I would like to use an H2 database in a Spring Boot application.
This is what I have in application.properties:
spring.datasource.name=testdb
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=whydoesthishavetobe
spring.datasource.password=sodifficult
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
This are the relevant lines in the build.gradle file:
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
When I check the connection for the H2 database, it's all good.
But despite this, when I POST new entities into the application, I see nothing getting created in the H2 database, and Hikari data source is getting used instead in the background, as I see from the logs.
Why is Spring ignoring the application.properties file and not using the H2 data source? How can I force it to use the H2 data source?
This is Spring Boot 2.3.4.RELEASE.
I guess you have multiple datasources and a datasource other tha H2 is being autowired as default.As Hirakicp is a connection pool not a db.
U need not get rid of Hirakicp rather set h2 datasources as primary
The below solution should work if you have multiple datasources ,
If you have multiple data source beans configured, it's just that spring is autowiring other data source to be used as a default source.
using #Primary annotation while declaring H2 Datasource bean should solve this.
Using this annotation will force spring to autowire the datult to h2 datasource.
in case you have not declared a datasource bean for H2 but have other datasource beans, you will need to declare the h2 bean and set it as primary using #primary annotation.
note - Hirakicp is a db connection object not a db .
Example -
#Bean("one")
public BasicDataSource dataSourceOne() {
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setUrl(env.getProperty("spring.a.connectionUrl"));
basicDataSource.setDriverClassName(env.getProperty("spring.a.DriverClass"));
basicDataSource.setUsername(env.getProperty("spring.a.username"));
basicDataSource.setPassword(env.getProperty("spring.a.password"));
// basicDataSource.setMaxActive(2);
return basicDataSource;
}
#Primary
#Bean("two")
public BasicDataSource dataSourceTwo() {
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setUrl(env.getProperty("spring.u.connectionUrl"));
basicDataSource.setDriverClassName(env.getProperty("spring.u.DriverClass"));
basicDataSource.setUsername(env.getProperty("spring.u.username"));
basicDataSource.setPassword(env.getProperty("spring.u.password"));
return basicDataSource;
}
I think this is happening because SpringBoot application creates its own in-memory embedded database while your database client creates its own in-memory embedded database.
I suggest you to change the database from in-memory to filesystem and see if the application and your database client shows the same data.
spring.datasource.url=jdbc:h2:file:/data/sample/testdb
You only need to change the database url to make it a file based database.
If you need to proceed with in-memory approach, you can connect to that via tcp so that both your application and client can use the same database.
spring.datasource.url=jdbc:h2:tcp://localhost/mem:testdb
What do you mean by Why is Spring ignoring the application.properties file and not using the H2 data source? Hikari is connection pool, not a datasource. If you would like to provide your own datasource, you have to inject a bean with the configuration of your interest.
Connection pool A connection pool is a cache of database connections maintained so that the connections can be reused when future requests to the database are required.
Datasource Is where data that is being used to run a report or gain information is originating from.
Check here for more on connection pools: https://www.baeldung.com/java-connection-pooling
But, if it the logging that you don't like, you can set the logger to error with org.zaxxer.hikari=error

spring boot sql database DML and DDL scripts

How i could define some schema and data to be inserted into db for
sql database in spring boot
Also could i do this for embedded databases
For example i am using two databases and i want to populate some data or define some schema and apply to different databases before application starts.
A file named import.sql in the root of the classpath is executed on startup if Hibernate creates the schema from scratch (that is, if the ddl-auto property is set to create or create-drop). This can be useful for demos and for testing if you are careful but is probably not something you want to be on the classpath in production. It is a Hibernate feature (and has nothing to do with Spring).
You can take a look in spring docs

Spring Boot schema.sql - drop db schema on restart

Hi I'm using Spring Boot version 1.5.9.
When using Spring Boot to initialize schema.sql for mysql database, it works all fine and the database schema is getting created successfully. But on restart of the application this schema.sql script is executing again and the application fails to start because the tables already exist.
I tried spring.jpa.hibernate.ddl-auto=create-drop option in application.properties but it does not have any effect (probably because it only works for Hibernate entities which I'm not using)
Is there a way to have Spring Boot to re-create schema from schema.sql every time on restart if the database is not in-memory one?
GitHub:
https://github.com/itisha/spring-batch-demo/tree/database-input
According to the documentation you can simply ignore exceptions by setting spring.datasource.continue-on-error property to true
Spring Boot enables the fail-fast feature of the Spring JDBC
initializer by default, so if the scripts cause exceptions the
application will fail to start. You can tune that using
spring.datasource.continue-on-error.
or even turn it off with spring.datasource.initialize set to false
You can also disable initialization by setting spring.datasource.initialize to false.
A workaround could be, to change the create statements in your schema.sql
from
CREATE TABLE test .....
to
CREATE TABLE IF NOT EXISTS test ...
use the IF NOT EXISTS statements
turn off automatic schema creation to avoid conflicts: add this line in your application.properties
spring.jpa.hibernate.ddl-auto=none

Categories