How to fire liquibase rollback script from spring application - java

I am using spring with liquibase to update my database. Since know I have not need to user rollback functonality, but the times come where I would like to make it work.
But I cant seems to fire it from my application.
I know that maven has plugin which helps with that, but until know I was not using it and when I add it I need to provide source and credentials to my database.
In this moment liquibase is configured in xml.
<bean id="liquibase" class="liquibase.integration.spring.SpringLiquibase">
<property name="dataSource" ref="p6spyDataSource"/>
<property name="changeLog" value="classpath:db.changelog-master.yaml"/>
.
.
</bean>
And in maven I have only dependency to liquibase-core.
And the place where I set liquibase.shouldRun is in application.properties
DataSource is taken from TomEE configuration server.xml file
So the question is if I can maybe somehow add maven plugin without adding credentials (should be taken from dataSource). Or is there other way to run rollback script from my changelog?

There are several related questions that have been posted previously about using Liquibase rollback with Spring Boot. This one seems the most similar to your post: Perform a liquibase:rollback from the command line when properties are in Spring-boot files (application.properties) and not liquibase.properties
Here is the answer as provided by Robert Kleinschmager:
The property names within springs application.properties and liquidate.properties are not compatible. You have three options
#1 just create a separate liquibase.properties file with the content you need - see liquibase doc as you only need to fix your current setup
#2 give the database parameters via command-line arguments
mvn liquibase:rollback -Dliquibase.rollbackCount=1 -Dliquibase.url=jdbc:postgresql://localhost:5432/comptesfrance -Dliquibase.username
see rollback goal for all arguments
#3 if you need a permanent solution, then you may add the liquibase properties into your application.properties and reuse them in the same file. i.e.
liquibase.url=jdbc:postgresql://localhost:5432/comptesfrance
spring.datasource.url=${liquibase.url}

Related

Spring can't locate a driver class that *is* in the classpath

I'm trying to run a springboot app on a tomcat server that includes a datasource that's able to communicate with a vault and change db credentials during runtime. The only change I've made in this code is adding some properties that are necessary to communicate with the vault, and changing the datasource configuration to include these vault changes.
I get the following error during startup:
Description:
Cannot determine embedded database driver class for database type NONE
However, in my application.properties file I DO have the driver class specified...
spring.datasource.hikari.driverClassName=com.ibm.db2.jcc.DB2Driver
and in the pom file, I have the correct dependency so the driver is infact included in the classpath... I even see the jar in Intellij's 'External Libraries' drop down.
Again, I've not made many changes besides adding in addtional properties for our vault... and changing the code inside our datasource config to use the vault.
I've compared my changes against another module in which I did the exact same thing, and didn't have this issue at all there.
Does anyone have any ideas as to why this is happening, or suggestions on what I can try?
I've tried including a #Import annotation on my #Configuration class, which points to the vault configuration. I've tried adding a #ComponentScan on my application class to try and really get it to look at the config and properties properly.
If any further detail is required please just let me know. Thanks in advance for any and all help that can be offered.
I have faced same problem and got resolved by below annotation
#SpringDataApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
please provide code snippet.So, i can debug it.

How do I use templating with Hibernate and Gradle?

I have a server that talks to a database that I need to test. I connect to the database using Hibernate and manage the dependencies using Gradle. I want to use separate tables in MySql for production and testing. So I have currently this line in hibernate.cfg.xml:
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/production_database</property>
But what I really want is for it to be something like:
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/${DATABASE_NAME}</property>
and then when I run gradle test, DATABASE_NAME can be set to "test_database_name", and when I run gradle jettyRun it'll still be "production_database". This seems like something that should be possible, but when I google for "hibernate teplating" I get references this other thing called HibernateTemplate that has nothing to do with what I want as far as I can tell. What's the syntax that'll make this happen for me?
You should move that property out of hibernate.cfg.xml, and into a database.properties file.
And, Then you can use gradle to modify this file depending upon the argument.
Please refer to Gradle Tasks for this.
ant.propertyfile(
file: "database.properties") {
entry( key: "connectionurl", value: "somevalue")
}

javax.mail.Session in cloudBees

I am developing a webapp in cloudbees platform and trying to add functionality for sending mail.
I am following https://wiki.cloudbees.com/bin/view/RUN/SendGrid documentation and as per the document we can get the mail session using below:
Context initCtx = new InitialContext();
Session session = (Session) initCtx.lookup("java:comp/env/mail/SendGrid");
But when running thie code in cloud i am getting:
java.lang.ClassCastException: javax.mail.Session cannot be cast to javax.mail.Session.
the problem seems to be with javax.mail.jar
i have downloaded the latest jar from https://java.net/projects/javamail/pages/Home .
As i understand the version which is required in cloud bees is different from what i am deploying.Can anyone help in getting correct jar for this particular purpose.
Note: I have added send grid to my stack in cloudBees.
I think you have more than one version of the javax.mail.
Indeed, the java mail session jars should be already provided by the container.
You can refer to this, as example: https://github.com/CloudBees-community/tomcat7-sendgrid-clickstart/blob/master/pom.xml
Try to remove your mail jar and if it still does not work and you are using maven try using the dependency plugin with
mvn dependency:tree -Dverbose
to check if you have conflicts with mails dependencies.
Duplicate Problem Resolved with Spring Framework on Cloudbees
I had the same problem only from Spring and can confirm it was from including javax-mail in the Maven dependencies (which also brings in the mail jar). After taking out the dependency/jar file I was having a problem with the constructor for org.springframework.mail.javamail.JavaMailSenderImpl not liking the type of the argument from jndi, however. At least the original error seemed to be objecting to the same class rather than saying it didn't know the type/name/etc. Finally, taking out passing the session to the constructor and putting it in the property (which in theory should do the same thing, I believe) fixed the problem:
<jee:jndi-lookup id="mailSource"
jndi-name="java:comp/env/mail/SendGrid"
expected-type="javax.mail.Session" />
<bean id="mailSender"
class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="session" ref="mailSource" />
</bean>

Liquibase JPA configuration of the referenceUrl

I am struggling to build the JPA annotated classes diff changesets against my database, using liquibase.
Still, I am very confused about few things.
I use the following :
liquibase.properties
#liquibase.properties
driver: org.postgresql.Driver
classpath: real_path/.m2/repository/org/postgresql/postgresql/9.2-1002-jdbc4/postgresql-9.2-1002-jdbc4.jar
url: jdbc:postgresql://localhost:5432/diquiz
username: postgres
password: postgres
referenceUrl: hibernate:ejb3:diQuiz
referenceUsername: postgres
referencePassword: postgres
changeLogFile: changelog-master.xml
and
java -jar real_path\liquibase-core-3.0.6.jar diffChangeLog
and a normal persistence.xml file with standard JPA configuration.
I get an error which says : Liquibase diffChangeLog Failed: java.lang.RuntimeException: Cannot find database driver: Driver class was not specified and could not be determined from the url (hibernate:ejb3:unit)
I am confused because the below answer says that we need a hibernate.cfg.xml file (even I have persistence.xml instead), but then he says that we can use some url's which are defined on wiki page.
Hibernate using JPA (annotated Entities) and liquibase
Wiki page says that if we need to use JPA, we can choose between three types of URL's.
hibernate:ejb3:myPersistenceUnit
hibernate:ejb3:com.example.MyConfigFactory
hibernate:ejb3:myPersistenceUnit?hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
So, I choose the first one, and I've set in the liquidbase.properties this as referenceUrl.
Also, on the wiki page it is mentioned : (https://github.com/liquibase/liquibase-hibernate/wiki)
If you are using the command line version of Liquibase, you simply
have to add the liquibase-hibernate[3|4].jar file to the
LIQUIBASE_HOME/lib directory.
I did this too.
Still, doesnt work. Can someone explain me somewhow what am I missing ?
Thanks a lot!
The problem is that you are calling liquibase with "java -jar". The Class-path line in the jar can't pick up additional jars from the lib directory and so the liquibase-hibernate.jar is not being included in the classpath.
Run liquibase using the sh/bat file included in the liquibase jar: real_path/liquibase[.bat] diffChangeLog

Dynamic Change of files directory for jdbc.properties and log4j.properties

I'm working in a Java Web Project.
I need to change the folder of the files "jdbc.properties" and "log4j.properties" depending of the environment, because testing, demo and release have diferent values for those files.
I have this folders and subfolders:
c:\myProject\conf\dev
c:\myProject\conf\test
c:\myProject\conf\demo
I need to put diferent jdbc.properties and log4j.properties files in each of those folders
c:\myProject\conf\dev\log4j.properties
c:\myProject\conf\dev\jdbc.properties
c:\myProject\conf\test\log4j.properties
c:\myProject\conf\test\jdbc.properties
c:\myProject\conf\demo\log4j.properties
c:\myProject\conf\demo\jdbc.properties
The three project are in the same Server and in the same Apache (It is a Web Project)
First i made some changes to use a windows system variable to get the parent folder (c:\myProject). To do that, i made this on Spring appContext file:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>file:${PARENT_FOLDER}/conf/dev/jdbc.properties</value>
</property>
</bean>
"PARENT_FOLDER" is defined on Windows environment variables/system variable
Those changes works OK.
But, as you can see, I always loking for file on "/conf/dev"
I need to make dynamic the "dev" part of the path.
I Can't use Windows environment variables/system variable because the 3 environments are deployed on the same Server.
I'm trying to use a "property" (using ) on web.xml, but I don't know how to find the property in my Spring appContext file.
I definy the property like this:
<env-entry>
<env-entry-name>ENVIRONMENT</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>Dev</env-entry-value>
</env-entry>
But I don't know how to access "ENVIRONMENT" property on Spring
I don't know what to do. I a little desperate
Can someone help me?
Thanks and sorry for my poor english
Have you considered using JNDI?
With JNDI you will define the db connection properties inside tomcat itself. This way your spring configuration is independent of the environment and you can deploy the same war on all environments. See also this.
If you need to run it locally that you can always use the 'new' spring environment profiles feature.
Other option (if JNDI is not an option and assuming you use maven) is the maven replacer plugin where you will generate the db.properties at build time.

Categories