Cannot add initial data to database with Spring Boot (Hibernate) - java

I use Hibernate in my Spring Boot app and populate the tables without any problem. However, I am trying to add 2 record to one of the populated table using import.sql on the classpath.
INSERT INTO role(id, role_type) VALUES(1, 'ADMIN');
INSERT INTO role(id, role_type) VALUES(2, 'USER');
I also set the following properties:
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.defer-datasource-initialization=true
spring.sql.init.mode=always
When I run the app, tables are created and the data is populated, and tables are created. However, I got "Error executing DDL : alter table user_role drop foreign key" error.
When I update spring.jpa.hibernate.ddl-auto as shown below, there is no error and tables are created. BUT, records are not inserted to the role table:
spring.jpa.hibernate.ddl-auto= update
So, how can I insert data when I run the app without any problem?

import.sql will only be executed provided that spring.jpa.hibernate.ddl-auto is set to create or create-drop.
Alternatively you can use data.sql it will be executed irrespective of hibernate.ddl configuration.
Using spring.jpa.hibernate.ddl-auto= update and data.sql should solve both of your error.
spring.sql.init.mode=always
spring.jpa.defer-datasource-initialization=true
spring.jpa.hibernate.ddl-auto= update
Use defer-datasource

Related

Spring Boot cannot generate table in a PostgreSql database

I have a Spring Boot app and I created a PostgreSql database in a Docker container. I can connect to that database using tools, but when I run my Spring Boot app, it cannot create table even if the following log is seen on debug screen:
Hibernate: drop table if exists public.employees cascade
Hibernate: create table public.employees (id bigserial not null, email varchar(255), first_name varchar(255), last_name varchar(255), primary key (id))
Here is my properties file (I use PostgreSql 9+, database name is employee_management_system):
spring.datasource.url=jdbc:postgresql://localhost:5434/employee_management_system
spring.datasource.username=postgres
spring.datasource.password=******
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQL92Dialect
spring.jpa.properties.hibernate.default_schema = public
spring.jpa.hibernate.ddl-auto = create
spring.jpa.show-sql = true
I do not use a DOckerfile or docker-compose.yml (I think I do not need for this step as I already have a container for my PostgreSql database). Any idea?
Seem like your spring-boot application have access to your database. Otherwise, you won't have the logs you put and you would have an exception when you start your application.
Maybe you have to check the way your are connected to your database (identifiers, schema, etc ..)?

How is H2 database different compared to Postgresql? Does H2 create tables on its own when used in a microservice

I'm new to programming and I'm trying to read a json and store in a database using springboot, when i use H2 i dont have to create table structure it creates on its own but when i use postgres i get errors that unable to find table. is there anyway to create tables automatically in postgres ?
How do they work and postgres is not able create tables on its own, Am i doing anything wrong?`
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.datasource.initialization-mode=always
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/MyDB
spring.datasource.username=postgres
spring.datasource.password=1234
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
There's a property you need to set for PostgreSQL to automatically create the tables on startup:
spring.jpa.hibernate.ddl-auto=update
Or if you want to start from a clean database everytime:
spring.jpa.hibernate.ddl-auto=create
For embedded databases like H2, Spring Boot will set spring.jpa.hibernate.ddl-auto=create automatically
See also this 12-year old question about why you should not do that in production:
Hibernate: hbm2ddl.auto=update in production?
In production, you should manage the database tables outside of your application, or use something like Liquibase or Flyway
If the database is embedded the default value of spring.jpa.hibernate.ddl-auto is create-drop. If not, default value is none.
Check this out - https://docs.spring.io/spring-boot/docs/1.1.0.M1/reference/html/howto-database-initialization.html

Is it possible to make Spring Boot JPA Hibernate application to automatically create tables with necessary columns and relations from JPA entities?

I am a newbie that only knows basics of Java Core. I have test task where I need to create simple REST Web Service with Spring Boot.
I wrote all the logic in Java Core, and now I try to wrap it in all these technologies.
I am using this guide:
https://spring.io/guides/tutorials/rest/
Here they have JPA entities and #Table annotation, where table name is specified, but there are no SQL scripts to create tables in this guide.
So I thought JPA will create database and tables for entities by itself, but when I uncomment #Table annotation it says "Cannot resolve table '<table_name>'"
I am using IntelliJ IDEA with Spring Boot Maven project with imported Spring Web, H2 and JPA (like the guide tells to do).
I also configured H2 Data Source and tested the connection: works fine. There is a schema, but no tables.
Here is my application.properties:
spring.h2.console.enabled=true
spring.h2.console.path=/h2_console
spring.datasource.url=jdbc:h2:~/kaylemains
spring.datasource.platform=h2
spring.datasource.initialization-mode=always
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.generate-ddl=true
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto = update
spring.jpa.show-sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
As in the guide, I add entities in LoadDatabase class like this:
#Bean
CommandLineRunner initTournaments(TournamentRepository repository) {
return args -> {
log.info("Preloading " + repository.save(new Tournament("Kayle Mains Competition: Summoner's Gorge", 16)));
};
}
So my question is: can I have file-stored H2 database and do everything with the it (including table creation) from my Java code?
OR it is necessary to create tables manually (by writing SQL scripts with CREATE TABLE) and construct them so that all entities work fine? (that means defining foreign key columns etc.), and only after that will JPA be able to work with this database? Do I need to add #Column annotation to every field, and JPA won't do it by itself for its Entities?
Why am I getting this error of "Cannot resolve table"? Of course it cannot be resolved because it does not exist yet, I thought JPA & Hibernate will create it for me based on entity classes...
Here in Baeldung you have all the information about the properties to ddl generation
Spring provides a JPA-specific property which Hibernate uses for DDL generation: spring.jpa.hibernate.ddl-auto.
create – Hibernate first drops existing tables, then creates new tables
update – the object model created based on the mappings (annotations or XML) >is compared with the existing schema, and then Hibernate updates the schema >according to the diff. It never deletes the existing tables or columns even if >they are no more required by the application
create-drop – similar to create, with the addition that Hibernate will drop >the database after all operations are completed. Typically used for unit testing
validate – Hibernate only validates whether the tables and columns exist, otherwise it throws an exception
none – this value effectively turns off the DDL generation
We have to set the value carefully or use one of the other mechanisms
to initialize the database.
If the problem is still present go to Settings -> Inspections, and uncheck the option "Unresolved database references in annotation"

Cannot populate database with liquibase

I'm building a small spring-boot application. I'm using spring-data-jpa to create the database schema and liquibase to populate it with test data.
application.properties:
spring.datasource.url=jdbc:postgresql://localhost:5432/book-db
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=admin
spring.datasource.password=lTIDDYz3n3jD3BeYaAJz
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
According to the documentation no configuration for liquibase is required if I have a gradle dependency and master changeLog under the default path.
db.changelog-master.yaml:
databaseChangeLog:
- changeSet:
id: 1
author: jb
changes:
- sqlFile:
path: db/migration/insert-books.sql
insert-books.sql:
--liquibase formatted sql
--changeset admin:1
delete from book;
insert into book (id, title)
values (nextval('seq'), 'Functional Programming for Mortals');
commit;
I have tried it with and without commit. The tables databasechangelog and databasechangelog are created successfully and contain the migration (insert-books).
The migration goes through, because if I add an invalid insert (to some table that does not exist), I get the exception:
ERROR: relation "xxx" does not exist
How to populate the database with data in insert-books.sql script using liquibase?
Don't use both, liquibase and JPA, to manage the DB structure. If you want to use liquibase, set JPA (Hibernate) to just validate the schema and manage the schema within liquibase.
spring.jpa.hibernate.ddl-auto=validate
The problem with your solution is in the order of operations. When your application starts, it first runs liquibase, which inserts the data, then JPA is started and the schema is created from scratch.
Try dropping the schema before running the app, I bet the migration (liquibase) will fail.
Liquibase has to be in charge of the schema, there is a way to add liquibase to an existing database, but it again makes liquibase the owner of the schema:
Using liquibase on the existing database

How to run DDL after Spring auto create db?

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

Categories

Resources