• Specifying Different Databases for Unit and System Testing

    Quality software requires thorough testing. Most applications today also utilize databases for persistent storage. As such, being able to test your application against your target database is important, be it unit testing, functional testing, or system testing.

    One of the key points in unit testing code that performs database operations is that the database must always be in a known state before the test is run. This usually requires removing all data and inserting the necessary data pre-conditions. Fortunately, there are tools that would facilitate this type of testing (e.g. DBUnit).

    Unfortunately, the approach above produces a simple, yet annoying problem. Since the unit tests will use the default database configuration, it will utilize the same database as when you deploy the application to do some system testing. What if you were debugging some UI bug and have already added some sample test data to the database? Running the unit test would remove all the data. Pretty annoying if you asked me.

    I will present here a simple technique to solve this problem that utilizes Spring Framework and Maven.

    The first step is to transfer the database configuration to a properties file. Here’s the spring xml configuration to do that:


    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="
              http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
              http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
     
     <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations" value="classpath:spring.properties"/>
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
     </bean>
     
     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
     </bean>
     
     <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitManager" ref="persistenceUnitManager"/>
     </bean>
     
     <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
        <property name="defaultDataSource" ref="dataSource"/>
        <property name="persistenceXmlLocations">
          <list>
            <value>classpath:META-INF/persistence.xml</value>
          </list>
        </property>
     </bean>
     
     <!– Needed so the @PersistenceUnit annotation is recognized –>
     <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
     
     <!– Transaction manager for a single EntityManagerFactory (alternative to JTA) –>
     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
     </bean>
    </beans>

     And here’s the spring.properties file.


    jdbc.driverClassName=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost/prod
    jdbc.username=root
    jdbc.password=root

     The key items to note are:

    1. Configure the JPA persistence manager (spring bean = persistenceUnitManager) to utilize an external data source (Note: Don’t forget to also remove any data source configurations in your persistence.xml file).
    2. Add the PropertyPlaceholderConfigurer bean to enable you to configure the bean properties via a properties file.
    3. Set the systemPropertiesModeName to SYSTEM_PROPERTIES_MODE_OVERRIDE. This will enable system defined properties to override those defined in the properties file.
    4. Configure your data source to utilize the properties defined in your properties file.

    So now you are able to configure your data source to use a properties file and is by default utilizing the production database. To configure it to utilize a different database when running unit tests, configure the maven-surefire-plugin to pass a different database URL via the system properties. Here’s a quick snippet:


            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-surefire-plugin</artifactId>
              <configuration>
                <useFile>true</useFile>
                <forkMode>once</forkMode>
                <childDelegation>false</childDelegation>
                <argLine>-Xmx512M</argLine>
                <workingDirectory>${basedir}</workingDirectory>
                <systemProperties>
                  <property>
                    <name>log4j.configuration</name>
                    <value>log4j-tests.properties</value>
                  </property>
                  <property>
                    <name>jdbc.driverClassName</name>
                    <value>com.mysql.jdbc.Driver</value>
                  </property>
                  <property>
                    <name>jdbc.url</name>
                    <value>jdbc:mysql://localhost/unit_test</value>
                  </property>
                  <property>
                    <name>jdbc.username</name>
                    <value>root</value>
                  </property>
                  <property>
                    <name>jdbc.password</name>
                    <value>root</value>
                  </property>
                </systemProperties>
              </configuration>
            </plugin>

     With this, every time you run the unit test cases, it will use the unit_test database, and when you deploy the application to do system testing, it will use the prod database.

  • Reusing JPA models using embedded entities and composition

    We’ve all heard of the debate regarding inheritance vs composition. Composition is certainly favored more over inheritance unless there is an “is-a” relationship between two classes.

    In the ORM world, specifically in JPA, composition is achieved using join-relationships (i.e. One-To-One, One-To-Many, Many-To-One, Many-To-Many), often overlooked is the functionality to embed a class in your models using the Embeddable and Embedded annotations. In this article I hope to present a simple design pattern that demonstrates the usefulness of this feature.

    To demonstrate this feature, we will use the following problem scenario:

    “You are tasked to create a simple bulletin board service. The requirements are simple, a user will login, after which he or she can create a bulletin post or comment on other public posting. Additionally, other users can edit a bulletin posting or the same user can edit his or her comment, but the system must be able to show who created the posting or made the last change and when it occurred. It is not a requirement to track the change history, just the last update.”

    For our initial model design, we need two concrete entity classes, a Bulletin model for all bulletin postings and a Comment model to store comments. We will also include a mapped superclass to store common fields like the model id and optimistic lock. We now have the ability to store bulletin posting and comments associated with it in our database. How do we now keep track of updates to each entity?

    A simple solution would be to have a dateCreated, createdBy, dateUpdated, and updateBy field for each entity (we will refer to them as our auditing information). Here is where the inheritance vs composition decision comes in. Since both models require auditing information, do we create a superclass to encapsulate the functionality (inheritance) or do we create a separate field to store the auditing information (composition)?

    For this scenario, I will choose composition because:

      Non-invasive - using composition injects the auditing feature to the specific class that needs it, as oppose to inheritance where subclasses will inherit the auditing feature whether they need it or not.
      Flexible - using composition allows multiple features to be added to a class without worrying about the one parent class per class rule. Example, if you need to make a model auditable and ownable by a specific group of users, you can just add an auditing information and an ownership information property.
      Encapsulation - using composition encapsulates the data and behavior of the feature without mixing it with the data and behavior specific to the class.

    Provided below is the interface and embeddable class that will implement our auditing feature for each model.

    public interface Auditable {
        public AuditInfo getAuditInfo();
    
        public void setAuditInfo(AuditInfo auditInfo);
    }
    
    @Embeddable
    public class AuditInfo {
    
        @Column(length = 50)
        protected String createdBy;
    
        @Temporal(TemporalType.TIMESTAMP)
        protected Date dateCreated;
    
        @Column(length = 50)
        protected String updatedBy;
    
        @Temporal(TemporalType.TIMESTAMP)
        protected Date dateUpdated;
    
        // Methods/getters/setters removed for simplicity
    }
    

    The Embeddable annotation specifies that an entity can be embedded in another entity class.

    For our Bulletin and Comment model, we use the following implementations.

    @Entity
    @EntityListeners(AuditListener.class)
    @Table(name = "bulletin")
    public class Bulletin extends AbstractModel implements Auditable {
    
        @Column(length = 255)
        protected String title;
    
        @Lob @Basic(fetch = FetchType.EAGER)
        protected String body;
    
        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "bulletin")
        protected List comments = new ArrayList();
    
        @Embedded
        protected AuditInfo auditInfo = new AuditInfo();
    
        // Methods/getters/setters removed for simplicity
    
    }
    
    @Entity
    @EntityListeners(AuditListener.class)
    @Table(name = "comment")
    public class Comment extends AbstractModel implements Auditable {
    
        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "BULLETIN_id", referencedColumnName = "id", nullable = false, updatable = false)
        protected Bulletin bulletin;
    
        @Column(length = 255)
        protected String comment;
    
        @Embedded
        protected AuditInfo auditInfo = new AuditInfo();
    
        // Methods/getters/setters removed for simplicity
    
    }
    

    We use the Embedded annotation to specify that the field is an embeddable entity.

    You would also notice that we have an Auditable interface that contains a getter and setter. This interface plays an important role in providing type checking to our models when used together with EntityListeners. Provided below is a sample of our entity listener that will implement the auditing functionality.

    public class AuditListener {
    
        private final transient Logger log = LoggerFactory.getLogger(AuditListener.class);
    
        @PrePersist
        public void setCreatedBy(Auditable model) {
            model.getAuditInfo().setCreatedBy(UserContext.getCurrentUser());
            model.getAuditInfo().setDateCreated(new Date());
            log.debug("Auditing model on prepersist: " + model);
        }
    
        @PreUpdate
        public void setUpdatedBy(Auditable model) {
            model.getAuditInfo().setUpdatedBy(UserContext.getCurrentUser());
            model.getAuditInfo().setDateUpdated(new Date());
            log.debug("Auditing model on preupdate: " + model);
        }
    }
    

    With the Auditable interface, we are provided type checking such that only “Auditable” models can be used in the AuditListener. (Note: this also presents some problems in OpenJPA, since it uses reflection to invoke the entity listeners. An obscure type mismatch exception will occur, if a non-”Auditable” model is passed to the listener.)

    That’s it for using composition and embeddable entities in JPA. For a complete sample, you can download the source code here.