Is there a way to quickly get initial SQL script for the database that is being generated by hibernating through ddl-auto property?
I would like to get an initial SQL script for the flyway as a quick start.
use property spring.jpa.show-sql = true and it will print all script on console in format.
use ddl-auto as you did and take backup of schema for your respective DB and use that as initial script
example - mysql , postgres
You can see the DDL script generated by Hibernate in a Spring boot application by setting the logging level of Hibernate to debug mode in the application.properties file of your project.
logging.level.org.hibernate.SQL=DEBUG
Related
I have a spring boot application which is using Postgresql and also maven. It uses the Flyway migration to migrate database changes. I want to have a specific SQL file and run it by a command to insert some records for configuration whenever I want.
Could you please help me to handle this?
The specific topic is detailed here Spring Database Initialization.
Basically set the initialization values as you require:
spring.datasource.platform=postgres
spring.jpa.hibernate.ddl-auto=update
spring.datasource.initialization-mode=always
....
E.g. (there are much more options) if you place into resources the file data.sql it will be executed and you can add your fixtures.
For specific Flyway migrations you should check Execute Flyway Database Migrations on Startup.
Basically you add every new migration version script and it will be checked for every deployment.
As I've read the default name of the embedded H2 database in Spring Boot should be testdb, but if I try to connect to with the H2 Console, I get the following error:
Database "mem:testdb" not found, either pre-create it or allow remote database creation (not recommended in secure environments)
It works only if I set the name explicitly in the application.properties with the following parameter:
spring.datasource.url=jdbc:h2:mem:testdb
Since the application can connect to the embedded database without this configuration, there must be a different default name. But what is the default name of the automatically configured database?
Enable h2 console in application.properties as jurez said
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.jpa.show-sql=true
and then when you run the application in the console you will see something like this:
H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:2f5b7da9-0cd2-4fdd-98d2-5ef5f76391bc'
then you can use this JDBC URL to connect to the database from the h2-console
http://localhost:8080/h2-console
jdbc:h2:mem:2f5b7da9-0cd2-4fdd-98d2-5ef5f76391bc
you can specify your own name by adding the following property in the application.property file
spring.datasource.url=jdbc:h2:mem:testdb
remember since this is an in-memory database it will be dropped and recreated every time you run your application
h2 also has a persistent mode but it is not recommended, you can do that by adding the following configurations taken from the following tutorial Spring Boot and H2 in memory database - Why, What and How?
spring.datasource.name=yourdbname
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.initialize=false
spring.datasource.url=jdbc:h2:file:~/yourdbname;DB_CLOSE_ON_EXIT=FALSE;IFEXISTS=TRUE;DB_CLOSE_DELAY=-1;
spring.jpa.hibernate.ddl-auto = update
By default, memory databases are only accessible to the process in which they are running.
If you want to access it from H2 Console, you need to enable it in application.properties:
spring.h2.console.enabled=true
My question is simple. How to run any DDL statements after Spring's automatic schema creation?
I have set the following in my application-test.properties to auto create the database schema from the entity Java classes.
spring.jpa.hibernate.ddl-auto=create-drop
I'd like to change the data type of one column in one table after the schema is auto created.
I tried having a schema.sql file in the classpath, but that didn't help.
Any help please.
Scripts which you specify in script will run before it create database.
So when you fire Alter table command, you will get Table not found kind of error.
What I would suggest is to create database via SQL file only and set
spring.jpa.hibernate.ddl-auto=none so system wont create auto database.
Now to make your SQL file run, You can create the schema and initialize it based on the platform. Platform value is of spring.datasource.platform. Now you can create files schema-${platform}.sql and data-${platform}.sql which is processed by Spring Boot. It allows you to choose the database specific scripts if necessary. You can choose the vendor name of database(platform) like hsqldb, h2, oracle, mysql, postgresql, and so on.
I have tested with postgres and It worked for me. Sql file name was schema-postgres.sql
Set below properties in application.properties file
spring.jpa.database=POSTGRESQL
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/poc
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=none
spring.datasource.initialization-mode=always
My database.properties file is:
datasource.driver=org.h2.Driver
datasource.url=jdbc:h2:file:./test_database/comixed_db;create=true
datasource.username=sa
datasource.password=
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=false
hibernate.format_sql=true
hibernate.batch.size=20
hibernate.current.session.context.class=org.springframework.orm.hibernate5.SpringSessionContext
hibernate.generate_statistics=false
hibernate.enable_lazy_load_no_trans=false
When my application starts up I see I am able to see the tables by using the h2.bat tool and peeking at the database from a web browser. However, when I shut down the application and then go back to the database with the h2.bat tool the tables are all gone!
AM I doing something incorrectly with my hibernate configuration? I am not using create-drop but update since this code is currently in flux and I'd like the tables to be adjusted as changes occur. But that doesn't seem to be the issue since it's at app shutdown that the tables keep going away.
Any help would be appreciated.
If you want spring boot to catch your hibernate properties you should prefix them with spring.jpa, so:
spring.jpa.hibernate.ddl-auto=update
Otherwise, and that is the case in my opinion, spring will use the default create-drop options as it is dealing with an H2 in-memory database.
By adding the following line to applications.properties:
spring.jpa.hibernate.ddl-auto=update
Spring-boot stopped dropping tables when the application exits.
I have some problems with using a schema.sql file to create my sql schema when executing a junit test while this schema contains mysql specific expression. I have to add the mode=mysql to the H2 url.
For example something like this:
jdbc:h2:mem:testd;MODE=MYSQL
But Spring boot automatically uses the url defined in the enum
org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection with its url
jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE.
I have tried similiar approaches to get this to work, but spring does not take the spring.datasource.url=jdbc:h2:mem:testdb;MODE=MYSQL from my test-application.properties. All other settings from my test-application.properties have been read successfully.
If I let spring/hibernate create the schema (without the schema.sql file) with the javax.persistence annotations in my entities everything works fine.
Is there a simple way to add a mode?
Set
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MYSQL
in application-test.properties, plus
#RunWith(SpringRunner.class)
#DataJpaTest
#AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
#ActiveProfiles("test")
on the test class
I was having this same issue. It would not pick up the url when running tests. I'm using flyway to manage my scripts. I was able to get all of these working together by following these few steps.
Created a V1_init.sql script in src/test/resources/db/migration so that it is the first script run by flyway.
SET MODE MYSQL; /* another h2 way to set mode */
CREATE SCHEMA IF NOT EXISTS "public"; /* required due to issue with flyway --> https://stackoverflow.com/a/19115417/1224584*/
Updated application-test.yaml to include the schema name public:
flyway:
schemas: public
Ensure the test specified the profile: #ActiveProfiles("test")
I have tried similiar approaches to get this to work, but spring does not take the spring.datasource.url=jdbc:h2:mem:testdb;MODE=MYSQL from my test-application.properties
Did you try to append this parameters instead of rewriting the existing ones?
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MYSQL
All other settings from my test-application.properties have been read successfully.
I thought that file should be named application-test.properties.
I was able to run it with this config:
# for integration tests use H2 in MySQL mode
spring.datasource.url=jdbc:h2:mem:testdb;DATABASE_TO_LOWER=TRUE;MODE=MySQL;
spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
The main trick here is to force Hibernate to generate SQL scripts for MariaDB dialect because otherwise Hibernate tries to use H2 dialect while H2 is already waiting for MySQL like commands.
Also I tried to use more fresh MariaDB103Dialect for MariaDB 10.3 but it doesn't worked properly.
You need to set MYSQL mode on h2 and disable replacing of datasource url for embedded database:
Modify application-test.yaml
spring:
datasource:
url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;MODE=MYSQL
test:
database:
replace: NONE