Liquibase and Hibernate
Join the DZone community and get the full member experience.
Join For Freewe create an application called liquibasetryouts. the structure of the projects is as follows:
the dependencies are listed below
i have noticed that there is not alot of documentation about setting up liquibase with ant scripts. so i created an ant script for our application. here is the ant script:
<?xml version="1.0" encoding="utf-8"?>
<project name="liquibase-sample">
<property file="liquibase.properties"/>
<path id="lib.path" >
<fileset dir="lib1" />
</path>
<target name="update-database">
<taskdef name="updatedatabase" classname="liquibase.ant.databaseupdatetask"
classpathref="lib.path" />
<updatedatabase
changelogfile="${changelogfile}"
driver="${driver}"
url="${url}"
username="${username}"
password="${password}"
dropfirst="${dropfirst}"
classpathref="lib.path"/>
</target>
<target name="rollback-database">
<taskdef name="rollbackdatabase" classname="liquibase.ant.databaserollbacktask"
classpathref="lib.path" />
<rollbackdatabase
changelogfile="${changelogfile}"
driver="${driver}"
url="${url}"
username="${username}"
password="${password}"
classpathref="lib.path"
rollbacktag="${tag}"
>
</rollbackdatabase>
</target>
<target name="tag">
<taskdef name="tagdatabase" classname="liquibase.ant.tagdatabasetask"
classpathref="lib.path" />
<tagdatabase
changelogfile="${changelogfile}"
driver="${driver}"
url="${url}"
username="${username}"
password="${password}"
classpathref="lib.path"
tag="${tag}"
>
</tagdatabase>
</target>
<target name="generatechangelog">
<taskdef name="generatechangelogdatabase" classname="liquibase.ant.generatechangelogtask"
classpathref="lib.path" />
<tagdatabase
outputfile="${outputfile}"
driver="${driver}"
url="${url}"
username="${username}"
password="${password}"
classpathref="lib.path"
>
</tagdatabase>
</target>
<target name="diff-database">
<taskdef name="diffdatabase" classname="liquibase.ant.diffdatabasetask"
classpathref="lib.path" />
<tagdatabase
driver="${driver}"
url="${url}"
username="${username}"
password="${password}"
baseurl="${url}"
baseusername="${username}"
baseuassword="${password}"
outputdifffile="${outputdifffile}"
classpathref="lib.path"
>
</tagdatabase>
</target>
</project>
next we use hibernate now like my blog on the 30 may we use hibernate with jpa annotations. here is the configuration file:
<!doctype hibernate-configuration public
"-//hibernate/hibernate configuration dtd 3.0//en"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/liquibasetestdb</property>
<property name="connection.username">monty</property>
<property name="connection.password">some_pass</property>
<!– jdbc connection pool (use the built-in) –>
<property name="connection.pool_size">1</property>
<!– sql dialect –>
<property name="dialect">org.hibernate.dialect.mysqldialect</property>
<!–<mapping package="liquibase.database.pojo"/>–>
<mapping class="liquibase.database.pojo.users"/>
<!– <mapping resource="test/animals/orm.xml"/>–>
</session-factory>
</hibernate-configuration>
now the class files for this project are the same as the files used for the blog in the 30 may with one or two extra files. here is the uml diagram:
now we need some change logs that follow the liquibase specifications these will be as follows
included.changelog.xml
<?xml version="1.0" encoding="utf-8"?>
<databasechangelog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.7"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://www.liquibase.org/xml/ns/dbchangelog/1.7 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.7.xsd">
<preconditions>
<dbms type="mysql"/>
</preconditions>
<changeset id="1" author="gabriel">
<createtable tablename="news">
<column name="id" type="int" autoincrement="true">
<constraints primarykey="true" nullable="false"/>
</column>
<column name="title" type="varchar(50)"/>
</createtable>
</changeset>
<changeset id="2" author="gabriel" context="test">
<insert tablename="news">
<column name="title" value="liquibase 0.8 released"/>
</insert>
<insert tablename="news">
<column name="title" value="liquibase 0.9 released"/>
</insert>
</changeset>
<changeset id="3" author="gabriel" context="demo">
<insert tablename="news">
<column name="title" value="liquibase 1.0 released"/>
</insert>
</changeset>
</databasechangelog>
next included2.changelog.xml
<?xml version="1.0" encoding="utf-8"?>
<databasechangelog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.7"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://www.liquibase.org/xml/ns/dbchangelog/1.7 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.7.xsd">
<preconditions>
<dbms type="mysql"/>
</preconditions>
<changeset id="1" author="gabriel">
<createtable tablename="records">
<column name="id" type="int" autoincrement="true">
<constraints primarykey="true" nullable="false"/>
</column>
<column name="title" type="varchar(50)"/>
</createtable>
</changeset>
<changeset id="2" author="gabriel" context="test">
<insert tablename="records">
<column name="title" value="liquibase 0.8 released"/>
</insert>
<insert tablename="records">
<column name="title" value="liquibase 0.9 released"/>
</insert>
</changeset>
<changeset id="3" author="gabriel" context="demo">
<insert tablename="records">
<column name="title" value="liquibase 1.0 released"/>
</insert>
</changeset>
</databasechangelog>
included3.changelog.xml
<?xml version="1.0" encoding="utf-8"?>
<databasechangelog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.7"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://www.liquibase.org/xml/ns/dbchangelog/1.7 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.7.xsd">
<preconditions>
<dbms type="mysql"/>
</preconditions>
<changeset id="1" author="gabriel">
<createtable tablename="register">
<column name="id" type="int" autoincrement="true">
<constraints primarykey="true" nullable="false"/>
</column>
<column name="title" type="varchar(50)"/>
<column name="name" type="varchar(100)"/>
</createtable>
</changeset>
<changeset id="2" author="gabriel">
<droptable tablename="register"/>
<rollback changesetid="1" changesetauthor="gabriel"/>
</changeset>
</databasechangelog>
and included4.changelog.xml
and we need a liquibase.properties file:
changelogfile=included4.changelog.xml
driver=com.mysql.jdbc.driver
url=jdbc:mysql://localhost:3306/liquibasetestdb
username=monty
password=some_pass
#for diff between two databases
baseurl=jdbc:mysql://localhost:3306/liquibasetestdb
baseusername=monty
basepassword=some_pass
dropfirst=false
tag=version 1.4
outputfile=outputfile.xml
outputdifffile=outputfile.txt
when we add the file in our eclipse ant editor this will be the view:
now running rollback-database,as an example, we get:
buildfile: /home/gabriel/eclipse/eclipse/opensource-workspace/liquibasetryouts/build.xml
rollback-database:
[rollbackdatabase] lock database
[rollbackdatabase] successfully acquired change log lock
[rollbackdatabase] included4.changelog.xml is using schema version 1.7 rather than version 1.9
[rollbackdatabase] reading from `databasechangelog`
[rollbackdatabase] release database lock
[rollbackdatabase] successfully released change log lock
build successful
total time: 6 seconds
now in my project(which has similar classes to the project of my last blog 30 may) i have added the two extra classes hibernateschematests and liquibaseschematests.
here is the full listing of hibernateschematests:
here is the full listing of hibernateschematests:
/**
*
*/
package liquibase.database.tests;
import java.util.arraylist;
import java.util.list;
import junit.framework.testcase;
import org.hibernate.hibernateexception;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import org.hibernate.cfg.annotationconfiguration;
import org.hibernate.cfg.configuration;
import org.hibernate.dialect.dialect;
import org.hibernate.tool.hbm2ddl.databasemetadata;
/**
* @author gabriel
*
*/
public abstract class hibernateschematests extends testcase {
private annotationconfiguration ac;
public void assertdatabaseschema() throws exception {
string[] script = generatescript();
list differences = getsignificantdifferences(script);
asserttrue(differences.tostring(), differences.isempty());
}
private string[] generatescript() throws exception {
// configuration cfg = getconfiguration();
// sessionfactory sessionfactory = cfg.buildsessionfactory();
// session session = sessionfactory.opensession();
ac = new annotationconfiguration().configure();
sessionfactory sessionfactory = ac.buildsessionfactory();
session session = sessionfactory.opensession();
try {
dialect dialect = getdatabasedialect();
databasemetadata dbm = new databasemetadata(session.connection(),
dialect);
string[] existingscript = ac.generateschemacreationscript(dialect);
for (string s : existingscript)
system.out.println(s);
string[] script = ac.generateschemaupdatescript(dialect, dbm);
return script;
} finally {
session.close();
}
}
protected dialect getdatabasedialect() throws exception {
return (dialect) class.forname(
getconfiguration().getproperty("hibernate.dialect"))
.newinstance();
}
private list getsignificantdifferences(string[] script) {
list differences = new arraylist();
for (int i = 0; i < script.length; i++) {
string line = script[i];
if (line.indexof("add constraint") == -1)
differences.add(line);
}
return differences;
}
protected configuration getconfiguration() throws hibernateexception {
return ac;
}
}
now we have the listing of liquibaseschematests:
/**
*
*/
package liquibase.database.tests;
/**
* @author gabriel
*
*/
public class liquibaseschematest extends hibernateschematests {
/**
*
*/
public liquibaseschematest() {
// todo auto-generated constructor stub
}
public void test() throws exception {
assertdatabaseschema();
}
}
now running these tests can also give us a diff-log between the schema from our mapping files(where we used annotations) and the actually database.
so what is the actual difference in the two methods.? well liquibase gives an xml output and can tag the database. it is open source. using hibernate is powerful but only for developers what about dba’s and other users? also when using liquibase the developers will have to liaise with the dba to ensure smooth running. liquibase has the advantage of alot of stable built in functionality.
integrating ant scripts for liquibase into maven can yield some nice
functionality
see this post on gabriel jeremiah campbell's blog:
http://gabrieljeremiahcampbell.wordpress.com/2010/06/06/liquibase-and-hibernate/
Opinions expressed by DZone contributors are their own.
Trending
-
Revolutionizing Algorithmic Trading: The Power of Reinforcement Learning
-
What ChatGPT Needs Is Context
-
Implementing a Serverless DevOps Pipeline With AWS Lambda and CodePipeline
-
How To Use Pandas and Matplotlib To Perform EDA In Python
Comments