Maven, Flex, and LiveCycle DS (Part 2)

Core module (with Hibernate)

I created a new module called core and added it to my existing Java/Flex multi-module Maven project. It just has a regular JAR packaging type. I moved the following entity classes and DAOs to the new core module:

  • flex.samples.crm.company.Company
  • flex.samples.crm.company.CompanyDAO
  • flex.samples.crm.employee.Employee
  • flex.samples.crm.employee.EmployeeDAO
  •  

I modified the entity classes to use JPA annotations, like so:

import javax.persistence.Entity;
. . .
@Entity
public class Company {. . .}
. . .
@Entity
public class Employee {. . .}

I modified the DAO classes by extracting the interface and creating an implementation that uses Hibernate (via AppFuse’s GenericDaoHibernate). The resulting interface and implementation class looks like this:

import org.appfuse.dao.GenericDao;
import flex.samples.crm.model.Company;

/**
 * Data access object interface for company entity.
 */
public interface CompanyDao extends GenericDao {
    List findCompanies(String name, String industry) throws DaoException;
    Company getCompany(int companyId) throws DaoException;
    Company create(Company company) throws DaoException;
    void update(Company newVersion, Company previousVersion, List changes)
        throws DaoException, ConcurrencyException;
    void delete(Company company) throws DaoException, ConcurrencyException;
}
. . .
import org.appfuse.dao.hibernate.GenericDaoHibernate;
import flex.samples.crm.dao.CompanyDao;
import flex.samples.crm.dao.ConcurrencyException;
import flex.samples.crm.dao.DaoException;
import flex.samples.crm.model.Company;
/**
 * Company DAO implementation using Hibernate.
 */
public class CompanyDaoHibernate extends GenericDaoHibernate
    implements CompanyDao {
    . . .
} 

After the above changes, I now have the following classes (note the slight modification in the location/package of the classes).

  • flex.samples.crm.model.Company
  • flex.samples.crm.model.Employee
  • flex.samples.crm.dao.CompanyDao
  • flex.samples.crm.dao.EmployeeDao
  • flex.samples.crm.dao.hibernate.CompanyDaoHibernate
  • flex.samples.crm.dao.hibernate.EmployeeDaoHibernate
  •  

I added the following dependencies to my POM.

    <dependencies>
        <dependency>
            <groupId>org.appfuse</groupId>
            <artifactId>appfuse-hibernate</artifactId>
            <version>2.0.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>hibernate3-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
            <components>
                <component>
                    <name>hbm2ddl</name>
                    <implementation>
                         annotationconfiguration
                    </implementation>
                </component>
            </components>
            <componentProperties>
                <drop>true</drop>
                <jdk5>true</jdk5>
                <namingstrategy>
                    ${hibernate.naming.strategy}
                </namingstrategy>
                <propertyfile>
                    target/test-classes/jdbc.properties
                </propertyfile>
            </componentProperties>
        </configuration>
        <executions>
            <execution>
                <phase>process-test-resources</phase>
                <goals>
            <goal>hbm2ddl</goal>
                </goals>
            </execution>
        </executions>
        <dependencies>
            <dependency>
                <groupId>${jdbc.groupId}</groupId>
                <artifactId>${jdbc.artifactId}</artifactId>
                <version>${jdbc.version}</version>
            </dependency>
        </dependencies>
            </plugin>
        </plugins>
    </build>

    <properties>
        <hibernate.naming.strategy>
            org.hibernate.cfg.ImprovedNamingStrategy
        </hibernate.naming.strategy>
        <hibernate.annotations.version>
            3.3.0.ga
        </hibernate.annotations.version>
        <hibernate.version>3.2.5.ga</hibernate.version>

        <hibernate.dialect>
            org.hibernate.dialect.MySQLInnoDBDialect
        </hibernate.dialect>
        <jdbc.groupId>mysql</jdbc.groupId>
        <jdbc.artifactId>mysql-connector-java</jdbc.artifactId>
        <jdbc.version>5.0.5</jdbc.version>
        <jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
        <jdbc.url>
            <![CDATA[jdbc:mysql://localhost/crm?
            createDatabaseIfNotExist=true&
            useUnicode=true&characterEncoding=utf-8]]>
        </jdbc.url>
        <jdbc.username>username</jdbc.username>
        <jdbc.password>password</jdbc.password>
        <jdbc.databaseName>MySQL</jdbc.databaseName>
    </properties>

Note that I’ve added a Hibernate3 Maven plugin, and using it to create the database schema via hbm2ddl goal.

After successfully building the core module, I’m now ready to move back to the web module and instantiate the DAOs and assemblers as Spring configured beans.

Web module (with Spring)

I added some new dependencies to my web module.

        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>crm-sample-config</artifactId>
            <version>1.0-SNAPSHOT</version>
            <classifier>resources</classifier>
            <type>zip</type>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>crm-sample-core</artifactId>
            <version>1.0-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.transaction</groupId>
                    <artifactId>jta</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
            <version>2.5.4</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.transaction</groupId>
                    <artifactId>jta</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.2.2</version>
        </dependency>

        <dependency>
            <groupId>${jdbc.groupId}</groupId>
            <artifactId>${jdbc.artifactId}</artifactId>
            <version>${jdbc.version}</version>
        </dependency>

Note that we’ve added the new core module as a dependency. We also added Spring and Commons DBCP. Also note that we’ve excluded the JTA dependencies to avoid conflicts with the web container. Otherwise, we’ll end up with the same “unable to access a UserTransaction” problem.

To use Spring as the factory, I followed the instructions at Christophe Coenraets’ blog and used the SpringFactory written by Jeff Vroom (LiveCycle Data Services architect). Note that this changes the services-config.xml and data-management-config.xml files in the config module.

My Spring configuration looks something like this.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <!-- For JDBC settings and future properties files -->
    <bean id="propertyConfigurer"
        class="org.springframework...PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
            </list>
        </property>
    </bean>

    <!-- JNDI DataSource for J2EE environments -->
    <!--<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/xxx"/>-->

    <bean id="dataSource"
        class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="maxActive" value="100"/>
        <property name="maxIdle" value="30"/>
        <property name="maxWait" value="1000"/>
        <property name="defaultAutoCommit" value="true"/>
        <property name="removeAbandoned" value="true"/>
        <property name="removeAbandonedTimeout" value="60"/>
    </bean>

    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory"
        class="org.springframework...AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=${hibernate.dialect}
                hibernate.query.substitutions=true 'Y', false 'N'
                hibernate.cache.use_second_level_cache=true
                hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
            </value>
        </property>
        <property name="namingStrategy">
            <bean class="${hibernate.naming.strategy}" />
        </property>
    </bean>

    <bean id="companyDao"
        class="flex.samples.crm.dao.hibernate.CompanyDaoHibernate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <bean id="companyAssembler"
        class="flex.samples.crm.company.CompanyAssembler">
        <property name="companyDao" ref="companyDao"/>
    </bean>

    <bean id="employeeDao"
        class="flex.samples.crm.dao.hibernate.EmployeeDaoHibernate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <bean id="employeeAssembler"
        class="flex.samples.crm.employee.EmployeeAssembler">
        <property name="employeeDao" ref="employeeDao"/>
    </bean>

</beans>

Note that I’ve modified the assembler classes (CompanyAssembler and EmployeeAssembler) slightly to use the CompanyDao and EmployeeDao interfaces.

And that’s it! I now have a Maven-based build of the CRM app (from LCDS samples) that uses Flex, Hibernate (annotations), Spring, and LCDS. Next, I’ll try to use Cairngorm in the ria module, and some AS3 code generation via Granite DS AS3 code generator.

If you would like to get a copy of the entire source, just let me know (by posting a comment).

This is my first try in using Maven to build a Flex app. Comments and suggestions are very welcome.

Advertisements

3 Responses to “Maven, Flex, and LiveCycle DS (Part 2)”

  1. François Says:

    I’d love to have a look at your code !
    You may also be interested in my new maven blazeds maven archetype:

    http://www.jroller.com/francoisledroff/entry/a_blazeds_xdoclet_spring_hibernate

  2. Wendy Dou Says:

    I am very interested in how you use maven 2 to build flex/lcds app. I tried different flex maven plugins (ServeBox and Israfil), I runing the error related to LCSD as followings:
    RPC Fault faultString=”[MessagingError message=’Destination ‘webPersonClient’ either does not exist or the destination has no channels defined (and the application does not define any default channels.)’]” faultCode=”InvokeFailed” faultDetail=”Couldn’t establish a connection to ‘webPersonClient'”]

    My application workflow is Flex/LCDS/EJB, I am able to build/run it successfully using eclipse flex plugin, now I want to build swf file using maven flex plugin, I did build successfully, however, when I run, I got above error. It looks I may need set lcds configuration when build.

    If possible, can you send me the info about how to configure and set pom.xml in order to use maven to build.

    Greate thanks in advance!
    Wendy

  3. Bailey Says:

    Thanks for this!

    I have gone through the BlazeDS stack a few weeks ago for a personal project, but now after setting up the local repositories for LCDS and trying your adjustments I cannot seem to get it deployed and am currently being stuffed full with stacktraces from the JBoss.

    When I find my solution I’ll be sure to post my errors and how I coped, here.

    If you could hit me up with a peek of the project in it’s entirety, I’m sure that would greatly help my BlazeDS transition to LCDS.
    That would be much appreciated!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: