How to unlock Liquibase Lock with Spring? - java

My service based on Spring 2.4.3 and use liquibase 4.3.1, deploy with Jenkins.
I have next problem- liquibase lock(Kibana logs):
Application run failed
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'liquibase' defined in class path resource
[org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]:
Invocation of init method failed; nested exception is
liquibase.exception.LockException: Could not acquire change log lock.
Currently locked by my-service since 10/29/21, 3:37 PM
Unfortunatelly I have no access to DB directly to update DATABASECHANGELOCK.
I tried this solution but without any result..
How to unlock liquibase without DB data loss?
Thanks in advance.

One of the ways to solve this problem permanently is to switch to session locking. This means that the Liquibase lock will be released automatically when the database connection used by Liquibase is closed.
If you are using one of the following DBs: MySQL, MariaDB, PostgreSQL, Oracle then you are lucky. Just use library Liquibase Session Locking and add it to your dependencies. This will replace LockServiceStandard with session locking and the problem will be gone permanently.
You can read more details in my blog post: Fix 'Liquibase Update Failed: Could not acquire change log lock' permanently and forget about it

If your CI system can configure the app to run the db migration, you should be able to run the release-locks command.
docker run --rm -t liquibase/liquibase release-locks \
--url="jdbc:dbserver:1433;database=mydatabase" \
--username=user \
--password=password
You can also use environment variables:
LIQUIBASE_COMMAND_URL = SPRING_DATASOURCE_URL
LIQUIBASE_COMMAND_USERNAME = SPRING_DATASOURCE_USERNAME
LIQUIBASE_COMMAND_PASSWORD = SPRING_DATASOURCE_PASSWORD

If someone interesting- I solve this case.
I add entity & dto - liquibaseLock and controller, service, repo.
After that comment liquibase implementation in build.gradle, push and deploy this version, unlock DB; comment out liquibase and push & deploy )
Now it works and I have proven solution )

Related

Can't run my Quarkus app after adding JPA

I'm trying to learn Quarkus, but after adding a JPA dependency the app doesn't initialize anymore.
This is the added dependency:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
Following are the errors I'm having:
[org.tes.uti.TestcontainersConfiguration] (build-47) Attempted to read Testcontainers configuration file at file:/home/fhb/.testcontainers.properties but the file was not found. Exception message: FileNotFoundException: /home/fhb/.testcontainers.properties (No such file or directory)
After that Quarkus keeps on and gets the following error:
Caused by: java.lang.RuntimeException: io.quarkus.runtime.configuration.ConfigurationException: Model classes are defined for the default persistence unit <default> but configured datasource <default> not found: the default EntityManagerFactory will not be created. To solve this, configure the default datasource. Refer to https://quarkus.io/guides/datasource for guidance.
This is my application.properties file:
quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=postgres
quarkus.datasource.password=admin
quarkus.datasource..jdbc.url=jdbc:postgresql://localhost:5432/quarkus-social
quarkus.datasource.jdbc.max-size=16
I think that Quarkus is trying to run tests and for that it needs the .testcontainers.properties file, which I've never created. Anyways I don't want to create that file in /home/fhb/, so theres a way to specify that file location?
Besides thatI would like to know if Testcontainers has something to do with unit tests, which I would like to add to my quarkus application.
Thanks in advance for your help.
I guess the problem is a small typo.
Change from
quarkus.datasource..jdbc.url=jdbc:postgresql://localhost:5432/quarkus-social
To
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/quarkus-social
If you don't specify the URL of the database and run in dev or test mode, Quarkus uses test containers to start one database for you.
There are tutorials on quarkus.io/guides/datasource.
About tests, you can use test containers or one in memory database as H2. You can find all this on Quarkus guides.

How to introduce liquibase in midle of spring boot maven based project

`I have already running project and trying to introduce liquibase in middle of project.
This is spring boot maven based project.
I am following steps.
1.liquibase.properties
url=jdbc:postgresql://localhost:5432/cc
username=postgres
password=deadline123
driver=org.postgresql.Driver
outputChangeLogFile=src/main/resources/db/changelog/db.changelog-master.yaml
runOnChange=true
referenceUrl=jdbc:postgresql://localhost:5432/cc
referenceUsername=postgres
referencePassword=deadline123
changelogFile=src/main/resources/db/changelog/db.changelog-master.yaml
diffChangeLogFile=src/main/resources/diff.yaml
Run command to generate changelog for current DB state
mvn liquibase:generateChangeLog
Then run command to sync changelog and create entry in DB
mvn liquibase:changelogSync
Starting my application but it's throwing error relation already exist. I can't figure out why liquibase is executing already executed changeset? I am using liquibase 4.6.3
Liquibase doesn't compare changes against your actual tables, it only keeps track of what changesets have already been executed (it creates another table for that called databasechangelog).
That being said, you have to make sure liquibase executes your changesets with a precondition that says 'if anything fails, mark it as executed'. It can be achieved like so:
<preconditions onFail="MARK_RAN">
<not>
<tableExists tableName="person"/>
</not>
</preconditions>
This example as well as much more information could be found on https://www.liquibase.com/blog/adding-liquibase-on-an-existing-project
Issue was with file path src/main/resources/db/changelog/db.changelog-master.yaml
liquibase:changelogSync adds file path as above in log sync and liquibae on start actually takes classpath classpath:/db/changelog/db.changelog-master.yaml

Flyway can't find classpath:db/migrations

I just started right now a new project in Intellij using Spring Boot ver 2.1.3 and Flyway 5.2.4 with Java 11.
After try to start my project i got :
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flyway' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.flywaydb.core.Flyway]: Factory method 'flyway' threw exception; nested exception is java.lang.IllegalStateException: Cannot find migrations location in: [classpath:db/migration] (please add migrations or check your Flyway configuration)
I have the following folders:
As you can see i have "db/migration" but without any migration, i just started right now. Debugging the class FlywayAutoConfiguration i got the following:
So, i tried to return all files in "classpath:", see:
Note that i just have "application.properties" file.
It is not that much useful or accurate answer.
But This issue make you frustrated so that i give this solution.
Note: Strange but it's true, Sometime it's not allow copy paste because your folder created db.migration and it expact db->migration(It's not same in this scenario). So whenever you start from scratch. Go to the resource folder -> Create DB folder -> Create migration folder -> Create database file with Version_SubVersion__Name(As defined below).
Normally this happens in following cases,
Path is not proper try using set locations param value.
db.migrate folder not contain any file.
Check name of file : V1_1__(short_desc)
Try to run using, mvn compile flyway:migrate
In my case i already place sql file over there but still it gives same error,
Basically i place this sql file using copy paste from somewhere.
When i try to add one new file on same place using IDE (Intellij : Right click on migration folder -> new -> Flyway migration -> versioned migration), then it ask me(warning) about some delicate allowance(normally we mention in database configuration i also place there still), and it start working.
Flyway requires at-least one script, disable it until u need it by using following command in application.properties file
spring.flyway.enabled=false
I believe that Flyway requires at least one migration script to initialize. Try adding a simple sql creation script into your migration folder and give it another try. Alternatively you can disable the flyway dependency until you need it.
I had a similar error, and solved it as follows: I added these commands
spring.flyway.baselineOnMigrate=true
spring.flyway.check-location=true
spring.flyway.locations=classpath:db/migration
spring.flyway.schemas=public
spring.flyway.enabled=true
to application.properties
I had the same issue. When I created the directory, I simply typed db.migration - the same way one would do with package names. InteliJ will display both db.migration and db/migration directories as db.migration, so while it may look correct in IntelliJ, flyway requires the latter.
Even when having your migration files in the db/migration folder, flyway won't detect it.
Then you will have to fix this by explicitly setting the locations in your application.properties (or appliocation.yml) by adding:
spring.flyway.locations=classpath:db/migration
N.B: Also you need to have at least one script to initialize flyway, you can even put an empty one. But you need to have at least one script
As #Guy suggested in his answer, I created an SQL file in the migration folder and left it empty. Named v1_0__mock_flyway.sql in the migration folder classpath:db/migration. Error solved.
If you have tried everything above and it still does not apply the migrations.
Be sure you have followed the steps in the previous answers
A db.migration folder exists in your resources folder
The sql scripts are named with respect to the correct naming convention, such as V1__init.sql
The following config exists in your application.properties/application.yml
spring.flyway.locations=classpath:db/migration
Do a clean build
-> mvn clean
Then restart your spring boot app, this worked for me.

ambiguous mapping while deploying

I'm using Jenkins 1.6.20 (Git Client Plugin 1.18.0, Git Plugin 2.4.0) to get the Java application code from bitbucket.org and deploy it to Apache Tomcat 8.0.23.
The error appears while deploying and looks like:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/spr$
public java.util.List by.ipps.accounting.ws.PositionWS.getEmployeePost(java.lang.Long)
to {[/positionListJson/{id}],methods=[GET],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}: There is already 'resourceWS' bean method
public by.ipps.accounting.model.Employee.EmployeePost by.ipps.accounting.ws.ResourceWS.getEmployeePost(java.lang.Long) mapped.
bla-bla-bla ... so many errors ...
Caused by: java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'positionWS' bean method
public java.util.List by.ipps.accounting.ws.PositionWS.getEmployeePost(java.lang.Long)
to {[/positionListJson/{id}],methods=[GET],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}: There is already 'resourceWS' bean method
public by.ipps.accounting.model.Employee.EmployeePost by.ipps.accounting.ws.ResourceWS.getEmployeePost(java.lang.Long) mapped.
The problem is that the class (with annotation #Controller) PositionWS with method getEmployeePost was renamed to ResourceWS a week ago, so exists no more, so I should not get this error.
To fix this I have to create a blank PositionWS controller (with no methods in it), commit & push that to bitbucket (and delete (cus i really don't need it) later and commit & push).
It seems to be like a bug in any of the applications I use. I can't find out in which app there is a bug to report it. Tell me please, if anyone faced such problems.
The heart of the issue was in incorrect configuration of Jenkins, it was my fault.
When I was configuring Jenkins I set maven goal as "install", but it must be "clean install". According to this Jenkins never deleted old files and kept them, so got a lot of issues of different kinds and with different log messages.
Due to Jenkins working specialty it downloads project files and try to assemble it on path /var/lib/jenkins/jobs/<projectName>/workspace/target/.
So I've drop the data in this folder and afterwards set maven goal to "clean install" and that fixed the issue.

jhipster: how to avoid database update when running in PROD mode?

When I run my jhipster app in production mode (spring.profiles.active=prod) the database update is always executed. I need to avoid this behaviour because organizational policies require DB updates to be run manually by the DBA.
Is it possible?
UPDATE with answer:
Yes, it is possible. The way to do it is exactly what #julien-dubois said: in the application-prod.yml file add the following line:
liquibase.enabled: false
Warning, the application-prod.yml generated by jhipster already contains some liquibase configuration
liquibase:
context: prod
But do not add the "enabled" entry under that "liquibase" entry because it is ignored. You should add a new root level entry:
liquibase.enabled: false
liquibase:
context: prod
This is a common Spring Boot property
In your application-prod.yml you need to set liquibase.enabled=false

Categories

Resources