Hibernate : Why is it trying to drop/create database on startup? - java

I'm new with Spring. I finally succeeded to build my application with no error but when i'm looking to the output i have a lot of information that i don't understand.
First this error each tables, it seems to be a Hibernate/Spring bug :
Hibernate: alter table entity.administrationaction drop constraint FKjaafjywumaavhae5kjyo34gx5
2016-11-13 12:16:41.475 ERROR 2156 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: alter table entity.administrationaction drop constraint FKjaafjywumaavhae5kjyo34gx5
2016-11-13 12:16:41.475 ERROR 2156 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : ERREUR: la relation « entity.administrationaction » n'existe pas
Then this for each table :
Hibernate: drop table if exists entity.administrationaction cascade
Then this for each table :
Hibernate: create table entity.administrationaction (id serial not null, action int4, creation_date timestamp, entity_class varchar(255), entity_id int4, message varchar(255), administrator_id int4, primary key (id))
So it is like Spring was trying to drop all my database and recreate it. Why ? Is it normal or have i done something wrong ?

Place in application.properties/application.yml
spring.jpa.hibernate.ddl-auto=update
This property can be set with values
1. update (Update the schema if necessary)
2. create (create the schema and destroy previous data)
3. create-drop (create and then destroy the schema at the end of the session)
4. none (disable ddl handling)
5. validate (validate the schema , make no changes to the database)

Look for the hibernate.hbm2ddl.auto setting. Probably you have set it to create-drop.

Some additional information as I found myself here not understanding why Spring would default to create-drop:
spring.jpa.hibernate.ddl-auto String:
DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto" property. Defaults to "create-drop" when using an embedded database and no schema manager was detected. Otherwise, defaults to "none".
Source: Javadoc

spring.jpa.hibernate.ddl-auto=none
this worked for me and it didn't messed up with the table and just used it.

spring.jpa.hibernate.ddl-auto=validate
add this line in applications.properties file. This worked for me.

Related

Spring Boot Application: how to create shema using flyway on startup?

There is spring boot application.
Here is configuration:
spring
flyway:
locations: classpath:db/migration
baseline-on-migrate: true
schemas: ${app.db.schema}
placeholders:
schema: ${app.db.schema}
init-sqls: CREATE SCHEMA IF NOT EXISTS ${app.db.schema}
And it doesn't work.
I need to create db schema before flyway will run migrations.
Flyway tries to read database migration scripts from classpath:db/migration folder by default.
All the migration scripts must follow a particular naming convention - V<VERSION_NUMBER>__<NAME>.sql.
Create a new file named V1__Create_Tables.sql inside src/main/resources/db/migration directory and add the sql script, for example:
-- ----------------------------
-- Schema for helloservice
-- ----------------------------
CREATE SCHEMA IF NOT EXISTS helloworld;
-- ----------------------------
-- Table structure for user
-- ----------------------------
CREATE TABLE helloworld.users (
id BIGSERIAL PRIMARY KEY NOT NULL UNIQUE,
username VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
first_name VARCHAR(255),
middle_name VARCHAR(255),
last_name VARCHAR(255),
email VARCHAR(255),
enabled bool NOT NULL DEFAULT true,
account_locked bool NOT NULL,
account_expired bool NOT NULL,
credential_expired bool NOT NULL,
created_on timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_on timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE helloworld.users IS 'User table';
When you run the application, flyway will automatically check the current database version and apply any pending migrations. By default, no additional properties are required. You can also create a schema in this script. Or flyway will do it for you if you specify a non-existent scheme.
If you are using hibernate, check this property:
spring.jpa.hibernate.ddl-auto=validate
For more information, see the instructions.
There is documentation link: https://flywaydb.org/documentation/commandline/migrate#schemas
Actually FlyWay is responsible for creating schemas if they don't exist.
Here is an example in changelog-history table:

Liquibase seems to run changeset against database twice (or H2 database isn't getting cleaned)

So I'm trying to run integration tests in my jhipster application, which is currently (by default, haven't made any changes to the tests config) using a H2 database. I've run mvnw clean test and I get the following error:
2018-08-09 16:05:56.340 INFO 276 --- [ main] .f.t.r.CustomAuditEventRepositoryIntTest : No active profile set, falling back to default profiles: default
2018-08-09 16:06:06.159 INFO 276 --- [ main] c.f.t.config.MetricsConfiguration : Initializing Metrics Log reporting
2018-08-09 16:06:16.258 ERROR 276 --- [ main] liquibase : classpath:config/liquibase/master.xml: config/liquibase/changelog/20180725185152_added_entity_Driver.xml::20180725185152-1::jhipster: Change Set config/liquibase/changelog/20180725185152_added_entity_Driver.xml::20180725185152-1::jhipster failed. **Error: Table "DRIVER" already exists**; SQL statement:
CREATE TABLE PUBLIC.driver (id BIGINT NOT NULL, first_name VARCHAR(255), middle_name VARCHAR(255), last_name VARCHAR(255), birth_date date, gender VARCHAR(255), suffix VARCHAR(255), weight FLOAT4, height VARCHAR(255), eye_color VARCHAR(255), hair_color VARCHAR(255), is_organ_donor BOOLEAN, drivers_license_id BIGINT, address_id BIGINT, CONSTRAINT PK_DRIVER PRIMARY KEY (id), UNIQUE (drivers_license_id)) [42101-197] [Failed SQL: CREATE TABLE PUBLIC.driver (id BIGINT NOT NULL, first_name VARCHAR(255), middle_name VARCHAR(255), last_name VARCHAR(255), birth_date date, gender VARCHAR(255), suffix VARCHAR(255), weight FLOAT4, height VARCHAR(255), eye_color VARCHAR(255), hair_color VARCHAR(255), is_organ_donor BOOLEAN, drivers_license_id BIGINT, address_id BIGINT, CONSTRAINT PK_DRIVER PRIMARY KEY (id), UNIQUE (drivers_license_id))]
So the error "Driver table already exists" makes me think
A: Liquibase is running the changesets against the db when it doesn't need to, or maybe it's running them twice?
or
B: The H2 database isn't actually getting cleaned before liquibase runs
changesets.
Any ideas?
Update: Here are the properties related to hibernate and liquibase in the test directory's application.yml file:
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:h2:mem:TouchQuote2Backend;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
name:
username:
password:
jpa:
database-platform: io.github.jhipster.domain.util.FixedH2Dialect
database: H2
open-in-view: false
show-sql: false
hibernate:
ddl-auto: none
naming:
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
properties:
hibernate.id.new_generator_mappings: true
hibernate.cache.use_second_level_cache: false
hibernate.cache.use_query_cache: false
hibernate.generate_statistics: true
hibernate.hbm2ddl.auto: validate
liquibase:
contexts: test
I tried changing the hibernate ddl-auto property to validate and it still throws the same error.
Most likely you have Hibernate generating the schema due to default being create-drop. As per the Spring Boot docs, Appendix A:
spring.jpa.hibernate.ddl-auto= # DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto" property. Defaults to "create-drop" when using an embedded database and no schema manager was detected. Otherwise, defaults to "none".
Set spring.jpa.hibernate.ddl-auto=validate to only validate the schema created with Liquibase.

Hibernate configuration hbm2ddl.auto

I have such hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:postgresql://host:5432/app-dev</property>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="hbm2ddl.auto">validate</property>
...many mappings
</session-factory>
And the problem is that it's trying to update my database schema, but I want to disable that feature.
log from my application:
2015-08-29 16:29:57 ERROR SchemaUpdate:261 - HHH000388: Unsuccessful: create table myschema.public.mytable (id int4 not null, count int4, anotherid int4, onemoreid int4, primary key (id))
2015-08-29 16:29:58 ERROR SchemaUpdate:262 - ERROR: syntax error at or near "-" <<(mydatabase name contains "-" sign)
Position: 27
I also tried to leave hbm2ddl.auto tag empty or include 'none' value in it.
Remove the property <property name="hbm2ddl.auto">validate</property> entirely.
By default all options will be false and hibernate will not attempt to do any updates.
Remove Hibernatehbm2ddl.auto defaults to Hibernate not doing anything.
From the docs
The hbm2ddl.auto option turns on automatic generation of database
schemas directly into the database. This can also be turned off by
removing the configuration option, or redirected to a file with the
help of the SchemaExport Ant task.
Validate is the default property of hbm2ddl.auto, even if you dont specify hbm2ddl.auto property, then also it is by default validate. Secondly there is no such value as "none", there are only 4 options :
validate- it simply checks that table and its columns are existing in database or not an if a table does not exist or any column does not exist than Exception is thrown.
create - If the value is create than hibernate drops the table if it already exist and then creates a new table and executes the operation, this is not used in real time as the old data is lost from database.
update - If the values is update than hibernate uses existing table and if the table does not exist than creates a new table and executes operation. This is mostly and often used in real time and it is recommended.
create-drop - if the value is create-drop than hibernate creates a new table and after executing the operation it drops the table, this value is used while testing hibernate code.
Thanks
Njoy Coding

Appfuse 3.5 and DB2

I am trying to create a webapp using appfuse. By default appfuse configures the app to work with a MySQL database, however I'd like use a DB2 database. Since Appfuse uses hibernate and Spring this should be a fairly straightforward configuration change but I haven't been able to get it to work. I get the following error on all my SQL calls:
create table role (
id bigint generated by default as identity,
description varchar(64),
name varchar(20),
primary key (id)
);
HHH000389: Unsuccessful: create table role (id bigint generated by default as identity, description varchar(64), name varchar(20), primary key (id))
DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=;;imary key (id));END-OF-STATEMENT, DRIVER=4.19.26
Here is how I have configured hibernate and the jdbc connection:
<jdbc.groupId>com.ibm.db2</jdbc.groupId>
<jdbc.artifactId>db2jcc4</jdbc.artifactId>
<jdbc.version>10.5</jdbc.version>
<jdbc.driverClassName>com.ibm.db2.jcc.DB2Driver</jdbc.driverClassName>
<jdbc.url>jdbc:db2://<IP Address>:<Port>/<DBName>:currentSchema=<schemaName>;</jdbc.url>
<jdbc.username><username></jdbc.username>
<jdbc.password><password></jdbc.password>
<jdbc.validationQuery><![CDATA[SELECT 1 FROM sysibm.sysdummy1;]]></jdbc.validationQuery>
<hibernate.dialect>org.hibernate.dialect.DB2Dialect</hibernate.dialect>
I don't understand where I'm going wrong. I can use the same db2jcc4.jar and connection parameters to connect to the DB through netbeans and copy and paste the sql from above and it executes without error. So I don't believe it's a syntax error as the SQLCODE=104, SQLSTATE42601 indicates. I'm at a loss of what I'm doing wrong. Any help you can give me is greatly appreciated!
I'm not sure if this is the correct answer but it worked: I removed the validation Query.
If anyone knows of a better answer or why this worked please share.
Thank you!

Eclipse + MySql + Hibernate, a good intro?

I'm looking for a tutorial explaining how to work with these 3 technologies, found this one, but it's working with HyperSql DB (yeah, I edited hibernate.cfg.xml to connect with MySql... but I just received a bunch of errors).
Your table creation script is wrong for the hibernate generator strategy you're currently using. As I said, your primary key should be defined as autoincrement:
CREATE TABLE COURSES (
COURSE_ID int(11) NOT NULL AUTO_INCREMENT,
COURSE_NAME varchar(20) DEFAULT NULL,
PRIMARY KEY (COURSE_ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
You should let SchemaExport generate your DDL for you, it will typically prevent such mistakes ;)
You might try setting <generator class="identity">. But native should also be working if you have set the database column to be auto_increment.
Problem solved using "Toad for MySQL" for creating the table, when setting the column to be the primary key, I just cleaned the "Default value" and did set the AutoIncrement property to true.

Categories