How does production database creation work in Jhipster? - java

Having some issues when uploading my jhipster generated app to heroku, after some research I found out that some entity modifications I did while developing are not done in production db so some fields are missing.
I also added a field to User entity, so now I cannot even register/login while that field is missing from the table.
Would like to know how exacly the database generation works in prod mode so I can make it work. Could it be related to smth missing in liquibase changelog?(I'm absolutely new to liquibase so I'm a bit lost).
UPDATE:
The problem seems to be a missing column from "jhi_user" table. I need to create a database changelog to add that missing column, so I ran
"mvn liquibase:generateChangeLog"
I saw the correct changelog poping in the console, but no changelog was created under my changelogs folder. What am i doing wrong?

First, check that there is a migration file corresponding to your entity in the directory:
src/main/resources/config/liquibase/changelog/
Then confirm that the Heroku app has a Database by running:
heroku addons
Then run Maven to repackage your WAR file:
mvn install -Pprod -DskipTests
Then deploy again:
heroku deploy:jar target/*.war
JHipster will run migrations at boot time. If you are using Postgresql, you can inspect the tables by running heroku pg:psql and using commands like \d

The problem was changelogs were not beeing generated when i created entities from yo jhipster:entity command.
Solved the issue doing:
mvn liquibase:diff
Plus some hand-done changesets and adding them to master.xml.
After that:
mvn liquibase:dropAll
mvn liquibase:update
Then deployed to heroku and every table was created.

Related

JHipster updated entity with liquibase changelog

I started a project in JHipster 7.6. I generated my entities using jdl. Now I modified some of my entites in java. If I understand correctly, I have to generate a changelog for the liquibase and add it to the master xml. As is in the JHipster documentation I used the ./gradlew liquibaseDiffChangelog -PrunList=diffLog command. The problem is that it generated a changelog, with the total database structure, and not just the changes. Could you say what am I doing or thinking wrong?
Thank you in advance.

Flyway repair with Spring Boot

I don't quite understand what I am supposed to do when a migration fails using Flyway in a Spring Boot project.
I activated Flyway by simply adding the Flyway dependency in my pom.xml. And everything works fine. My database scripts are migrated when I launch the Spring Boot app.
But I had an error in one of my scripts and my last migration failed. Now when I try to migrate, there is a "Migration checksum mismatch". Normally, I would run mvn flyway:repair, but since I am using Spring Boot, I am not supposed to use the Flyway Maven plug-in. So what am I supposed to do?
there are several ways to perform a repair on the database. I personally prefer the simple SQL statement.
SQL Statement:
Just delete the row with the failed migration. After that you can run the migration again.
Run flyway directly
You can install Flyway local and run flyway repair in the console
Use the Flyway Maven Plugin
Add the Flyway Maven Plugin to your pom and run mvn flyway:repair. I don't think this contradict with the Spring Boot concept.
Extend Spring Boot
Spring Boot will call Flyway.migrate() to perform the database migration. If you would like more control, provide a #Bean that implements FlywayMigrationStrategy.
In the FlywayMigrationStrategy you can call the migrate or repair method from flyway. More Information is available in the Spring Boot Reference Guide.
I don't think the FlywayMigrationStrategy in the application is the right place to repair the database. A failed migration is a exception and should be handle outside the application.
You can do it through code by declaring the following bean.
#Bean
public FlywayMigrationStrategy cleanMigrateStrategy() {
return flyway -> {
flyway.repair();
flyway.migrate();
};
}
Flyway Maven Plugin
Just to add this info to #Daniel's answer
1.
...
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>4.1.0</version>
<configuration>
<url>jdbc:mysql://localhost:3306</url>
<user>root</user>
<password>root</password>
<schemas>
<schema>[your_schema]</schema>
</schemas>
</configuration>
</plugin>
...
2.
mvn flyway:clean
3.
mvn flyway:repair
PS.: if the step 2 and 3 don't work change the order.
More info on maven goals: https://flywaydb.org/documentation/maven/
When database migration fails, the migration is marked as failed in the schema history table (i.e flyway_schema_history) indicating manual database cleanup may be required. But if database supports DDL transactions, the migration is rolled back automatically and nothing is recorded in the schema history table. PostgreSQL, Amazon Redshift, MS SQL are few of the databases which support DDL transactions whereas Oracle Database, MySQL, MariaDB, Amazon Aurora does not support DDL transactions.
In case of failed migration entries, there are several options to repair it (only applicable for databases that do NOT support DDL transactions) as described by #daniel-käfer. I want to add another (may be easier way) to deal with failed migrations.
There are several callbacks supported by flyway, afterMigrateError is one of them. If we add a sql file with name afterMigrateError.sql then, it will be executed after each failed migrate runs. Therefore, we can simply create a file afterMigrateError.sql on default location of database migration folder (resources/db/migration) with sql command to remove failed migrations from flyway_schema_history table.
The sql command afterMigrateError.sql can be as mentioned below:
DELETE IGNORE FROM flyway_schema_history WHERE success=0;
This command looks for the table flyway_schema_history if it exists otherwise it will do no changes. Then it simply looks for the rows which has success column with 0 entry (actually this happen if migration fails , all successful migration will have value 1 in success column), then delete such entries. Now, we can simply change our latest migration file and correct it and run again.
Install flyway locally as said above, change directory into the installation then run (example for H2):
./flyway -url=jdbc:h2:/Users/mugo/dev/h2/das-boot -user=sa -password= repair

How start flyway manually in spring boot

How can I start flyway manually with Spring Boot? Because I have 2 dbs in my application, so after Springboot load the properties and before connect to DB, I need to run the flyway from my 2 dbs.
If I understand you correctly, you don't want to start flyway manually, but run it on two databases. Here is how:
create two Datasources and mark one as #Primary, the other (should be a bean) as #FlywayDataSource.
When flyway runs, it will automatically run on both data sources. see https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-execute-flyway-database-migrations-on-startup
You can use flyway maven plugin to populate your databases.
You can either have two properties file for each database and execute flyway using mvn -Dflyway.configFile=myConfig.properties
Or
you can provide the db properties while executing maven like mvn -Dflyway.user=myUser -Dflyway.schemas=schema1,schema2 -Dflyway.placeholders.keyABC=valueXYZ
But please note that you have to execute flyway maven task twice. Each time for one database. Like,
$mvn -Dflyway.configFile=db1.properties compile migrate
$mvn -Dflyway.configFile=db2.properties compile migrate
Refer https://flywaydb.org/documentation/maven/ for more information.
If you are fine with this maven approach you don't need spring to do flyway migration.

Jenkins deploying to multiple servers based on data in a SQL Table

Presently, I have many jenkins jobs deploying war files to multiple servers using jboss as maven plugin. I have created multiple post build maven goals to deploy to multiple instances. To enhance the setup, I need to read the data from a SQL table where the mapping exist for each project and instances. Based on the data, I need to dynamically change the instances(undeploy from previous instance and deploy on new instance) and do hot deployment. Any thoughts?
Instead of using DB, I would suggest you to use a simple source repo, e.g. git repo. You can have such mapping data in that file.
So when you do deployment, Jenkins would checkout the repo. Your script could read it and do deployment. The script could be bash, ruby or anything you think it's easy. The script for deployment could be put into the same source repo as well.
Later on, if you need to do any change, you just change the repo and push the change.
The whole idea is infrastructure as code. You should put everything into source control. Jenkins will be a single tool to invoke the script from your source repo.

How to update the JHipster project after updating JHipster generator?

I updated my JHipster installation as per this page by running the command
npm update -g generator-jhipster
But to update my application I am not sure where should I run the next command yo jhipster.
I tried running it from the root of existing project, but it asked me to enter the name of the new project.
I tried running it at one level above the root of existing project, then also it asked me the name of the new project. But this time I entered the same name and the jhipster generation process ran. However there was no change in any of the major files like package.json or Gruntfile.js or bower.json
What is the correct way to update a JHipster project, once the JHipster generator is updated?
JHipster developers replied over twitter saying that yo jhipster has to be executed at the project root folder.
Following [jhipster releases] (https://jhipster.github.io/2015/05/31/jhipster-release-2.14.2.html):
How to upgrade
Update your version of JHipster with:
npm update -g generator-jhipster
And then you can update your project when you run again
yo jhipster
You can also update your entities by running again the entity sub-generator, for example if your entity is named Foo
yo jhipster:entity Foo
JHipster now has a page on Upgrading an application.
https://jhipster.github.io/upgrading-an-application/
TL;DR
Running the upgrade sub-generator
Go into the application’s root directory:
cd myapplication/
To upgrade your application, type:
yo jhipster:upgrade
If you want to run the upgrade sub-generator even if no new JHipster version is available, type:
yo jhipster:upgrade --force
If you want to update all entities you need to run
yo jhipster --with-entities
from the root of your project
Our jHipster monolithic project is based on an older build of the generator, and still reliant on bower / angularjs for the client. Thus the auto-update ability would never work.
I've been manually updating spring-boot-starter-parent every other sprint to try and bring it up into 2.x parity, but am still unable to leave the 1.5.x version stream due to various dependency issues with (mainly) Hibernate.
As a possible suggestion if you're in the same boat with your own monolithic project:
Pull down select versions of the jhipster-generator
Generate a "hello world" starter monolithic project
Compare the generated pom.xml with your own project
Compare the generated entity and configuration files with your own project
Run below command at the root of your project. Also, make sure to delete nodemodules and target folders before upgrading the project.
yo jhipster:upgrade
jhipster --force --with-entities this is how i do it (npm)

Categories

Resources