Importing Data with spring boot - spring-boot

I have flyway and spring-boot working correctly, but I can't seem to wire up my spring.datasource.data correctly.
If I have a file src/main/resources/db/seeds/one_project.sql. I have tried the following inside my application.properties file.
# fully qualified path
spring.datasource.data=file:///fully/qualified/path/db/seeds/one_project.sql
# classpath specific
spring.datasource.data=classpath:/db/seeds/one_project.sql
# relative path
spring.datasource.data=/db/seeds/one_project.sql
The only thing I can actually get to work is to copy one_project.sql to src/main/resources/schema.sql ( even copying it to src/main/resources/data.sql does not work.
Is there something I am completely missing from the documentation?
I have been following along the documentation here.
Thanks in advance for the help!

Stuck at that quite long.
My context: Spring Boot 2.2.6 + Hibernate 5.4 + script.sql in classpath(src/main/resources).
To make script executed at application start I was need to add in application.properties:
spring.datasource.initialization-mode=always
spring.jpa.hibernate.ddl-auto=update
spring.datasource.data=classpath:script.sql
And remove all comments BEFORE the actual code and BETWEEN code in script.sql.
Or if you need comments, add SELECT 1; on the next line after the line with comment. Because the next line after commented one seems to be ignored. No matter how many line breaks after line with comment you paste.

As i can see it, Spring Boot executes the data scripts if one of the following conditions is true:
The schema.sql script is present and the initialization is enabled (spring.datasource.initialize=true)
If JPA and Hibernate is used and autoconfigured with Spring Boot: The property hibernate.hbm2ddl.auto is present (the value doesn't matter, you can give it an empty string or just "validate") and the initialization is enabled (spring.datasource.initialize=true).

TL;DR
Create a blank schema.sql if you want your data.sql to run.
Also as stated in a comment it must execute one line such as `select 1` or `select 1 from dual`
You said
The only thing I can actually get to work is to copy one_project.sql to src/main/resources/schema.sql
Which makes me think it's evident you don't have a schema.sql
So just create a blank schema.sql and then it will run one_project.sql
Source Code -https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializer.java
As you can see it gathers the schema locations and if schema resources are empty then it doesn't continue to run the data.sql (this is at the top of the runSchemaScripts() method)

The way I got it working was by using the following properties
spring.datasource.data=classpath:prod.sql
spring.datasource.url=jdbc:mysql://localhost:3306/DATABASENAME?useSSL=false
spring.datasource.username=USERNAME
spring.datasource.password=PASSWORD
spring.datasource.initialization-mode=always
spring.datasource.initialization-mode=always seems to do the trick

Try using classpath*, like the following:
spring.datasource.schema=classpath*:db/seeds/your_schema.sql
spring.datasource.data=classpath*:db/seeds/one_project.sql

As of Spring Boot version 2.7 and onwards the provided here solution of
spring.datasource.initialization-mode=always
spring.jpa.hibernate.ddl-auto=update
spring.datasource.data=classpath:script.sql
will stop working since the properties spring.datasource.data and spring.datasource.initialization-mode have been removed from spring boot. The replacements spring.sql.init.data-locations and spring.sql.init.mode should be used instead.
So the solution would be
spring.sql.init.mode=always
spring.jpa.hibernate.ddl-auto=update
spring.sql.init.data-locations=classpath:script.sql
See relevant Spring Boot 2.7 changelog

Related

Deprecated configuration property 'spring.datasource.initialization-mode'

This is going to be the spring back-end of a project that I am working on. I am able to create tables from my model classes in Postgres database however I wasn't able to put static data to the tables.
I created a data.sql file in resources with bunch of insert commands.
This is how my application.properties looks like:
spring.datasource.url=jdbc:postgresql://localhost:5432/springtest
spring.datasource.username=
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.format_sql=true
spring.datasource.initialization-mode=always
The compiler(Intellij) is crossing a line over
"spring.datasource.initialization-mode"
with the message:
Deprecated configuration property
'spring.datasource.initialization-mode'
It also suggest me to use the replacement key spring.sql.init.mode=always however this does not work as well. I need the program to execute the SQL commands in data.sql.
Since Spring Boot 2.5.0 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.
Additional info: github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.5-Release-Notes
I was able to figure it out by changing
spring.datasource.initialization-mode=always
to
spring.sql.init.mode=always
and renaming data.sql to import.sql

Disable Envers in properties file

I have already referred to this question: Spring Boot 2 - disable Envers, but the answer did not work for me.
I am using Spring Boot and would like to disable Envers in the properties file without having to go into my code and remove any #Audited annotations or such.
I have tried the following to no avail:
hibernate.integration.envers.enable=false
spring.jpa.properties.hibernate.integration.envers.enable=false
spring.jpa.properties.org.hibernate.integration.envers.enable=false
hibernate.integration.envers.enabled=false
spring.jpa.properties.hibernate.integration.envers.enabled=false
spring.jpa.properties.org.hibernate.integration.envers.enabled=false
hibernate.envers.autoRegisterListeners=false
spring.jpa.properties.org.hibernate.envers.autoRegisterListeners=false
I cannot speak specifically to the integration with Spring Boot, but you should be able to force it to be disabled by supplying a custom hibernate.properties file shown below:
# this disables hibernate envers, even if its on the classpath
hibernate.integration.envers.enabled=false

Externalizing configuration for Hibernate Search

I am running hibernate search with spring boot. I have written a working configuration for my application. How ever, i want to externalize my configuration and use ./config/hibernate.properties instead of src/main/resources/hibernate.properties. After copying my properties file to the desired location, i am getting and exception:
nested exception is java.io.FileNotFoundException: class path resource [hibernate.properties] cannot be opened because it does not exist
Anyone with any idea on how i should tell spring to read my configuration file?
Move your configuration to an src/main/resources/application.properties file and prepend spring.jpa.properties. everywhere, so hibernate.dialect will become spring.jpa.properties.hibernate.dialect, for example.
Then you can use Spring features to move your configuration wherever you want. To move it to ./config/application.properties I suppose you will have to add #PropertySource("./config/application.properties") to one of your #Configuration classes, or something similar.
I'm sure you can also keep the hibernate configuration in a separate file (separate from the rest of your application configuration).
See https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html for more details about externalizing configuration in Spring Boot.
For some reason, it seems hibernate-search will prevent application from starting as long as a hibernate.properties configuration file does not exist. After trying for a while without success, i found a work around for my problem.
First, i created an empty hibernate.properties file and place it under src/main/resources.
Secondly, i moved all hibernate-search configurations to application.properties as follows:
spring.jpa.properties.hibernate.search.default.indexmanager = elasticsearch
spring.jpa.properties.hibernate.search.default.elasticsearch.host = http://my-server.com
spring.jpa.properties.hibernate.search.default.elasticsearch.index_schema_management_strategy = CREATE
spring.jpa.properties.hibernate.search.default.elasticsearch.required_index_status = yellow
This way, the application will start and spring will get all configuration from the externalized configuration as documented here.

Why I can't find my tables in H2 schema / How can I validate which H2 schema my Spring boot app is working with?

I'm running a spring boot app
didn't have any setting for h2 other than maven
when i'm connecting to the h2 console i can see the tables that were supposed to be created for two entities
i connected with the JDBC URL: jdbc:h2:mem:testdb (which is supposed to be the default)
Is there a way to make sure what schemas is H2 currently running/ or some log file for H2 ?
in my application.properties i have this:
spring.h2.console.enabled=true
spring.h2.console.path=/h2
I read somewhere that H2 initializing itself upon login, but a demo i was watching these were the exact steps taken , so not sure that is the case.
these are the settings in the H# console:
You can explicitly instruct spring boot to create and connect to a particular schema in H2 with config as below.
spring.datasource.url=jdbc:h2:~/test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
This creates a datasource of name test database in h2 in file mode. There would be a file called test.db in your home folder which would be the data file for the database.
DB_CLOSE_ON_EXIT property decides to recreate the database on every restart.
There is an easier way to tell Spring JPA the default schema for your H2 data source by just adding the "SET SCHEMA {default schema}" in the datasource url, e.g.:
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS testdb\\;SET SCHEMA testdb
I actually saw the right schema all along
The reason I thought I wasn't seeing the right schema was - the JPA Entities I expected to see, were not there.
I then found that this was because I didn't name the package for the JPA entities correctly
I named it "domain" (see pic):
I should have named it com.example.domain as can be seen:
This is because Spring Boot looks is doing a #ComponentScan "under" the package with the main class , so I had to prefix the "domains" with the name of the package that the main class resides in, which is com.example.
For me I had to check the log when I run Sprinboot
jdbc:h2:mem:9967b201-6b59-4925-acb3-d2e50dc5d9a5. --> this can be any other auto generated UUD
Adding this to your JDPC URL in the browser will let you see the tables that you created.

Spring Boot, Hibernate Search properties

How to provide Hibernate Search parameters when using Spring Boot?
...
spring.datasource.driverClassName=org.postgresql.Driver
hibernate.search.jmx_enabled=true
hibernate.search.default.directory_provider=filesystem
hibernate.search.generate_statistics=true
hibernate.search.lucene_version=LUCENE_CURRENT
hibernate.search.default.indexBase=/mypath-to-index
It does not care what I provide. Default settings always get applied.
I think below code does not have anything to process properties related to Hibernate Search. Can that be the issue?
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java
You can put them in the application.properties file if you put "spring.jpa.properties." in front of the property names.
Example:
spring.jpa.properties.hibernate.search.jmx_enabled=true
spring.jpa.properties.hibernate.search.default.directory_provider=filesystem
spring.jpa.properties.hibernate.search.generate_statistics=true
spring.jpa.properties.hibernate.search.lucene_version=LUCENE_CURRENT
spring.jpa.properties.hibernate.search.default.indexBase=/mypath-to-index
Spring will take any properties under spring.jpa.properties.* and pass them along (with the prefix stripped) once the EntityManagerFactory is created.
Got it working.
Put another property file named "hibernate.properties" inside src/main/resources with below content.
hibernate.search.jmx_enabled=true
hibernate.search.default.directory_provider=filesystem
hibernate.search.generate_statistics=true
hibernate.search.lucene_version=LUCENE_CURRENT
hibernate.search.default.indexBase=/mypath-to-index

Resources