Old Business
Getting back to an issue I had earlier with validation logic on some of the entity properties, I started looking into what it would take to call the field setters in the object constructor. Fortunately, I have a lot of warnings turned on in my IDE, so it can gently remind me (or encourage me to research why) some things I wanted to code were bad ideas. This was one of them. So, the first step would have been to change out setting the field directly in the constructor with a call to the setter. Sounds simple enough, now we have all the validation logic on the field in one place! But, now I get a warning from the IDE – you shouldn’t call a method in the constructor that can be overridden. Fine. So, I’ll go an make the setter final. That lead me off on a different trail with PropertyVetoChangeEvent so I could notify classes that use the method of bad input data and allow other objects to add more “business logic” to determine valid values to set (you know, the kind of things one would do by overriding the setter). After all that, I see another warning from the IDE – methods of persistent properties should not be final. Fine, time to do some research. Then I find in the Java EE 7 Tutorial, section 37.1.1, Requirements for Entity Classes – “The class must not be declared final. No methods or persistent instance variables must be declared final.” Well, alrighty then. Now I see why Spring continues to be a thing. The specs seem to encourage anemic domain models. There has to be a way to have a more robust domain object. The “logic” that I had in there wasn’t anything too complex so… enter Bean Validation! Now, all the code that I had in two places are replaced by two simple annotations on the field – @NotNull, and @Size(min, max).
@Basic(optional = false)
@Column(name = "givenname", nullable = false, length = 50)
@NotNull
@Size(min = 1, max = 50)
private String givenName;
This also means that the setter now just simply sets the field to the value passed in. The unit tests for these need to be updated, and a new test dependency is needed for a validation implementation.
<dependencies>
...
<!-- Hibernate Validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.2.Final</version>
<scope>test</scope>
</dependency>
</dependencies>
public class PersonTest {
private Validator validator;
@Before
public void setUp() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
@Test
public void testConstructor() {
Person testMe = new Person("", null);
Set&amp;lt;ConstraintViolation&amp;gt; violations = validator.validate(testMe);
assertEquals(violations.size(), 1);
}
@Test
public void testSetGivenName() {
Person testMe = new Person("Smith", "John");
testMe.setGivenName(null);
Set&amp;lt;ConstraintViolation&amp;gt; violations = validator.validate(testMe);
assertEquals(violations.size(), 1);
}
}
New Business
With that little bit cleared up, we can move on now to persisting the entities into a more permanent database. For this, I have chosen to use PostgreSQL 9.3, which I have used on a couple of past projects with great success.
PostgreSQL Configuration
After installing PostgreSQL (and pgAdmin so that we have a decent visual admin tool), we need to alter the password for the postgres user. We do this because by default, there is no password, and pgAdmin won’t work if you do not have a password for a login role (user). So, a little shell command will clear this up (set the password to whatever you want, hopefully something a little more secure than this).
sudo -u postgres psql -c “ALTER USER postgres PASSWORD 'postgres';”
Now, using pgAdmin, we can create some login roles, databases, and schemas. We shall start with the login role that will own the databases, and it shall be named “lee7”.

Set the password, but leave the expiration date blank.

Select the create databases and create roles checkboxes.

Accept the changes, and then we will move on to the login role for the contact application, “contact”. Follow the same procedures as above, but do not give this user the ability to create databases or roles. Now, a new database is needed for the application, so we will create it, and make the lee7 login role the owner.

Set a few more options about the database, and then accept the changes.

Now, create a schema to hold the data for the contact application. I have plans on adding more applications/modules in the future, each of which will be separated into their own schemas. You could also separate them into different databases, but that would make query joins more difficult than necessary.

Next, we need a separate database (lee7_test) for running the integration tests so we do not mix automated test data with manual test data or production data. We can just use the existing database as a template for the new one to a save a few configuration steps. Note that pgAdmin will complain if there are any connections to the source database when doing this, so make sure everything is disconnected first.

JBoss Configuration
If you want to use the web admin for JBoss, you will first need to create a management user which will then log into the management console (port 9990). Here, JBOSS_INSTALL_DIR is wherever you have JBoss installed. For me, it would be /opt/wildfly-8.0.0.Final for the main installation, ~/.m2/arquillian/contact/wildfly-8.0.0.Final for the installation that Arquillian uses when running integration tests.
$JBOSS_INSTALL_DIR/bin/add-user.sh admin Admin --silent=true
You will also need to install the PostgreSQL JDBC driver and configure a datasource. I defer to http://www.mastertheboss.com/jboss-datasource/configuring-a-datasource-with-postgresql-and-jboss/wildfly, which does a fine job of explaining the process. Note that the datasource name I used is contactDS.
persistence.xml Configuration
The persistence.xml file needs a couple of tweaks to use the new datasource:
<jta-data-source>java:jboss/datasources/contactDS</jta-data-source>
The property for the schema generation should be removed. All database functions from this point are handled with Liquibase. I have also turned off the options for Hibernate to show and format the SQL commands in the log for the main configuration, but left it turned on for the test configuration.
Liquibase Configuration
In the src/main/resources directory of the project, we create conf and db directories to hold configuration and Liquibase changelog files, respectively. The configuration files for Liquibase are simply .properties files, and an environment name in the file name for use when we want to pick an environment specific configuration. Each one contains the database connection information, along with some Liquibase behavior attributes.
driver=org.postgresql.Driver
url=jdbc:postgresql://localhost:5432/lee7
username=contact
password=contact
verbose=true
dropFirst=false
promptOnNonLocalDatabase=true
contexts=dev
driver=org.postgresql.Driver
url=jdbc:postgresql://localhost:5432/lee7_test
username=contact
password=contact
verbose=true
dropFirst=true
promptOnNonLocalDatabase=true
contexts=test
The main differences are which database is used in each, and that in test we drop everything before running the changesets to make sure we have a fresh start for the tests. The changelog files are standard XML. In the past, I have used one changelog file per ticket, one changelog file per feature, and a mixture of both. The Liquibase documentation suggests one per version, so that is what will be used here. It really does not matter what convention you want to use, just be consistent with it.
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<include file="changelog-1.0.0.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet id="create-legal-entity-sequence" author="nderwin">
<comment>Creating the primary key sequence for LegalEntity</comment>
<createSequence schemaName="contact" sequenceName="legal_entity_seq" />
</changeSet>
<changeSet id="create-organization" author="nderwin">
<comment>Creating the table for the Organization entity</comment>
<createTable schemaName="contact" tableName="organization">
<column name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="contact_organization_PK" />
</column>
<column name="name" type="VARCHAR(50)">
<constraints nullable="false" />
</column>
</createTable>
</changeSet>
<changeSet id="create-person" author="nderwin">
<comment>Creating the table for the Person entity</comment>
<createTable schemaName="contact" tableName="person">
<column name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="contact_person_PK" />
</column>
<column name="surname" type="VARCHAR(50)" />
<column name="givenname" type="VARCHAR(50)">
<constraints nullable="false" />
</column>
</createTable>
</changeSet>
</databaseChangeLog>
Maven Configuration
At this point, we can bring all the previous work together in the pom file. I was not satisfied with the integration tests firing off every time I started a build of the code, so I created an integration testing profile that contained the maven-failsafe-plugin configuration. This is also where the liquibase-maven-plugin is set to run.
<profiles>
<profile>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<id>integration-test</id>
<build>
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.2.2</version>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1102-jdbc41</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>process-test-resources</phase>
<goals>
<goal>update</goal>
</goals>
<configuration>
<driver>org.postgresql.Driver</driver>
<propertyFile>target/classes/conf/liquibase.test.properties</propertyFile>
<propertyFileWillOverride>true</propertyFileWillOverride>
<changeLogFile>target/classes/db/changelog.xml</changeLogFile>
<changelogSchemaName>contact</changelogSchemaName>
<defaultSchemaName>contact</defaultSchemaName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<configuration>
<parallel>methods</parallel>
<threadCount>10</threadCount>
<systemPropertyVariables>
<project.artifactId>${project.artifactId}</project.artifactId>
<arquillian.launch>wildfly</arquillian.launch>
</systemPropertyVariables>
<systemProperties>
<property>
<name>java.util.logging.manager</name>
<value>org.jboss.logmanager.LogManager</value>
</property>
</systemProperties>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<id>update-dev-database</id>
<build>
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.2.2</version>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1102-jdbc41</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>process-test-resources</phase>
<goals>
<goal>update</goal>
</goals>
<configuration>
<propertyFile>target/classes/conf/liquibase.dev.properties</propertyFile>
<propertyFileWillOverride>true</propertyFileWillOverride>
<changeLogFile>src/main/resources/db/changelog.xml</changeLogFile>
<changelogSchemaName>contact</changelogSchemaName>
<defaultSchemaName>contact</defaultSchemaName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
You will also note the update-dev-database profile. This allows for running the Liquibase change sets against the development database. For now, the profiles are working well, however I may look at moving all of this back into the main plugin area in the future and try to control it instead with command line switches. Remember, be Agile! For me, that means try it out, if it does not work as well as you hoped, find a better way.
As always, the full project can be found on GitHub. Questions and comments welcome.