user2475343
user2475343

Reputation: 11

Liquibase-maven plugin doesn't detect change between Hibernate hbm.xml and changelog.xml

I recently started on a project that utilizes MySQL database with Maven, Hibernate, and Liquibase, and I am not at all experienced in any of these so please forgive my naivety.

My goal for right now is trying to produce a diff changelog which I assume is a changelog that shows the changes between the normal changelog.xml and the hbm.xml

I inserted a new property, int age, into the hbm and was hoping that liquibase would detect that age is not included in the changelog, which would then produce a diff changelog saying there is an extra property or something like that. However it produced a changelog that was empty and said there was no changes.

The following are some of the parts of my project, but I only included those that seem relevant to the liquibase-maven:diff plugin:

User.java

package com.jnguyen.project;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class User extends CustomizableEntity{

    @Id
    private int id;

    private String username;
    private String firstname;
    private String lastname;
    private int age;   //new property which doesn't exist in changelog.xml yet

    public User() {}

    public void createUsername(String firstname, String lastname, int id) {
        this.username = firstname.substring(0,2).toLowerCase() + lastname.substring(0,2).toLowerCase() + String.format("%05d", id);
    }

    public void setAge(int age)
    {
        this.age = age;
    }

    public int getAge() {
        return this.age;
    }
    public void setUsername(String username) {
        this.username = username;
    }

    public String getUsername() {
        return this.username;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getFirstname() {
        return this.firstname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getLastname() {
        return this.lastname;
    }

    private void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return this.id;
    }

}

User.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping auto-import="true" package="com.jnguyen.project">

    <class name="User" table="users">
        <id name="id" column="id">
            <generator class="increment"/>
        </id>
        <property name="firstname"/>
        <property name="lastname"/>
        <property name="username"/>
        <property name="age"/>

        <dynamic-component insert="true" name="customProperties" optimistic-lock="true" unique="false" update="true">
        </dynamic-component>
    </class>

</hibernate-mapping>

changelog.xml

<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">

    <changeSet id="1.0_1" author="jnguyen">
        <createTable tableName="users">
            <column name="id" type="int(5)"/>
            <column name="firstname" type="varchar(20)"/>
            <column name="lastname" type="varchar(20)"/>
            <column name="username" type="varchar(20)"/>

        </createTable>
        <addPrimaryKey columnNames="id"
                       tableName="users"/>
        <addAutoIncrement
                columnDataType="int(5) UNSIGNED ZEROFILL"
                columnName="id"
                incrementBy="1"
                startWith="1"
                tableName="users"/>

    </changeSet>

</databaseChangeLog>

liquibase.properties

promptOnNonLocalDatabase=false
changeLogFile=db/ddl/changelog.xml
url:hibernate:hibernate.cfg.xml
referenceDriver:com.mysql.jdbc.Driver
referenceUrl:jdbc:mysql://localhost:3306/test
referenceUsername:root
referencePassword:rootpass

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jnguyen.project</groupId>
    <artifactId>jnguyen.project</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>Hibernate Project</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.codehaus.grepo</groupId>
            <artifactId>grepo-query-hibernate</artifactId>
            <version>1.5.3</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.transaction</groupId>
            <artifactId>jta</artifactId>
            <version>1.1</version>
        </dependency>

        <dependency>
            <groupId>teamdev</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.5.8</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>

        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0-rev-1</version>
        </dependency>

        <dependency>
            <groupId>org.codehaus.mojo.hibernate3</groupId>
            <artifactId>maven-hibernate3</artifactId>
            <version>2.2</version>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-core</artifactId>
            <version>3.0.0-rc2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.25</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>com.springsource.org.hibernate.core</artifactId>
            <version>4.1.0.Final</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
            <version>2.5.6</version>
        </dependency>

        <!-- Spring AOP dependency -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>org.apache.commons.logging</artifactId>
            <version>1.0.4.v200706111724</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>net.customware.liquibase</groupId>
            <artifactId>liquibase-hibernate</artifactId>
            <version>2.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.2.2.Final</version>
        </dependency>

    </dependencies>

<build>
        <plugins>
            <plugin>
                <groupId>org.liquibase</groupId>
                <artifactId>liquibase-maven-plugin</artifactId>
                <version>2.0.5</version>
                <configuration>
                    <diffChangeLogFile>db/ddl/diffchangelog.xml</diffChangeLogFile>
                    <changeLogFile>db/ddl/changelog.xml</changeLogFile>
                    <propertyFile>db/liquibase.properties</propertyFile>
                    <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
                    <driver>com.mysql.jdbc.Driver</driver>
                    <url>jdbc:mysql://localhost:3306/test</url>
                    <username>root</username>
                    <password>rootpass</password>
                    <referenceDriver>com.mysql.jdbc.Driver</referenceDriver>
                    <referenceUrl>jdbc:mysql://localhost:3306/test</referenceUrl>
                    <referenceUsername>root</referenceUsername>
                    <referencePassword>rootpass</referencePassword>
                    <migrationSqlOutputFile>script.sql</migrationSqlOutputFile>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

My output would be the following after I run the liquibase-maven:diff plugin:

Output

"C:\Program Files\Java\jdk1.7.0_25\bin\java" "-Dmaven.home=C:\Program Files\apache-maven-3.0.5" "-Dclassworlds.conf=C:\Program Files\apache-maven-3.0.5\bin\m2.conf" -Didea.launcher.port=7545 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA 12.1.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\apache-maven-3.0.5\boot\plexus-classworlds-2.4.jar;C:\Program Files (x86)\JetBrains\IntelliJ IDEA 12.1.3\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher --fail-fast --strict-checksums org.liquibase:liquibase-maven-plugin:2.0.5:diff
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Hibernate Project 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- liquibase-maven-plugin:2.0.5:diff (default-cli) @ jnguyen.project ---
[INFO] ------------------------------------------------------------------------
[INFO] Parsing Liquibase Properties File
[INFO]   File: db/liquibase.properties
[INFO] ------------------------------------------------------------------------
[INFO] Executing on Database: jdbc:mysql://localhost:3306/test
[INFO] Performing Diff on database root@localhost @ jdbc:mysql://localhost:3306/test
INFO 6/20/13 12:47 PM:liquibase: Reading tables for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading views for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading foreign keys for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading primary keys for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading columns for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading unique constraints for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading indexes for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Sequences not supported for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading tables for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading views for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading foreign keys for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading primary keys for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading columns for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading unique constraints for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Reading indexes for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: Sequences not supported for root@localhost @ jdbc:mysql://localhost:3306/test ...
INFO 6/20/13 12:47 PM:liquibase: db\ddl\diffchangelog.xml exists, appending
INFO 6/20/13 12:47 PM:liquibase: No changes found, nothing to do
[INFO] Differences written to Change Log File, db/ddl/diffchangelog.xml
INFO 6/20/13 12:47 PM:liquibase: Successfully released change log lock
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.566s
[INFO] Finished at: Thu Jun 20 12:47:17 CDT 2013
[INFO] Final Memory: 8M/243M
[INFO] ------------------------------------------------------------------------

Process finished with exit code 0    

The diffchangelog.xml that was produced out of this:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"/>

As you can see, the output near the end said:

INFO 6/20/13 12:47 PM:liquibase: No changes found, nothing to do

despite adding an extra property into the hbm.

Clearly I am doing something wrong that it is not detecting the change, and I've tried to look over the liquibase-hibernate documentation multiple times but now I am stuck. I am sorry if my post seem large and if my code seems messy, I'm still learning. This is my also first time posting on stackoverflow, so forgive me please. Thank you!

P.S. if there is a need for the other parts of my project, I will submit them on request.

Upvotes: 1

Views: 3703

Answers (2)

lmm
lmm

Reputation: 17431

You've configured the databases the wrong way round. referenceUrl should be hibernate:hibernate.cfg.xml and url should be jdbc:mysql://localhost:3306/test.

Upvotes: 1

jmh
jmh

Reputation: 9356

The flow of your data is all wrong here.

Hibernate takes what it has found on the database and generates POJOs with the help of the .hbm.xml file.

Liquibase takes a changelog and applies it to a database.

So in order to change your database, you:

  1. Add a changelog entry for your change and test it
  2. Update your .hbm.xml file to reflect the changes in the changelog.

Now you will see liquibase applying your change since it is in the changelog. Liquibase does not know or care at all about what is in the .hbm.xml file. That file is just for hibernate to create POJOs.

Upvotes: 0

Related Questions