Adobe
Products
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
Student and Teacher Editions
More products
Solutions
Creative tools for business
Digital marketing
Digital media
Education
Financial services
Government
Web Experience Management
More solutions
Learning Help Downloads Company
Buy
Home use for personal and home office
Education for students, educators, and staff
Business for small and medium businesses
Licensing programs for businesses, schools, and government
Special offers
Search
 
Info Sign in
Welcome,
My cart
My orders My Adobe
My Adobe
My orders
My information
My preferences
My products and services
Sign out
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Adobe
Products Sections Buy   Search  
Solutions Company
Help Learning
Sign in Sign out My orders My Adobe
Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change. Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.
Qty:
Purchase requires verification of academic eligibility
Subtotal
Review and Checkout
Adobe Developer Connection / Flex Developer Center /

The Flex, Spring and BlazeDS full stack – Part 2: Writing the to-do list server

by Sébastien Arbogast

Sébastien Arbogast
  • http://sebastien-arbogast.com

Content

  • Creating a WAR module
  • Writing Java code to develop the interface
  • Configuring the MySQL database

Created

29 June 2008

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
BlazeDS Flex Hibernate MySQL XML

Requirements

Prerequisite knowledge

Prior experience working with Spring, Hibernate and MySQL is very helpful. Familiarity with MySQL databases, Java and XML is also useful.

User level

Intermediate

Required products

  • Flex Builder 3 (Download trial)
  • BlazeDS (Download trial)

Sample files

  • todolist2.zip (36 KB)

Additional Requirements

Spring

  • Download

Welcome to the second installment of this three-part article series. In Part 1 I described the process for creating and configuring a classic standalone Flex module built with flex-mojos. In this section, I'll continue with the development of the sample project (to-do list application) and describe how to create the back-end module, using Spring, Hibernate and MySQL. In Part 3 of this article series I'll cover how to connect the front-end of the application with the back-end using BlazeDS.

Creating a WAR module

In this section we'll get started creating the back-end of the to-do list sample application. First, open a command line in the todolist directory that we created in Part 1 of the series and run the following command:

mvn archetype:create \ -DgroupId=org.epseelon.samples \ -DartifactId=todolist-web \ -DarchetypeArtifactId=maven-archetype-webapp

The command above creates a new todolist submodule inside the root todolist module. Next, edit the POM of this newly created module to add the following dependencies:

<dependency> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> <version>2.5.2</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.5.4</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.5.4</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate</artifactId> <version>3.2.6.ga</version> </dependency>

The dependencies added above are required for Spring and Hibernate to work.

Last but not least, update the configuration of the Java compiler plug-in in this module so that we can use generics and annotations in our code. Add the following plug-in configuration to the project/build/plugins node:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin>

At this point we've set up the module for the back-end, to prepare it for development. In the next section, we'll build the interface for the to-do list service using Java.

Writing Java code to develop the interface

In the previous section we prepared the module for the back-end of the to-do list application. Now let's write the interface for our main service. Create an "org.epseelon.samples.todolist.business" package in src/main/java, and then create a TodoService interface inside, using the following code:

package org.epseelon.samples.todolist.business; import java.util.List; import org.epseelon.samples.todolist.domain.TodoItem; public interface TodoService { void remove(TodoItem todoItem) throws Exception; TodoItem save(TodoItem todoItem) throws Exception; TodoItem findById(TodoItem todoItem) throws Exception; List<TodoItem> getList() throws Exception; }

The TodoService interface above is a very classic example of a CRUD service. Notice that the TodoItem class is being used as both a parameter and a return type for some of these methods. Normally I would never do this in a project, because when you have a situation like this where several entities have links between them, you run the risk of encountering LazyInitializationException problems on the client side. This occurs when you attempt to access linked entities while outside of a Hibernate transaction. This is not considered a best practice and should be avoided. But for the purposes of this sample project, it will work for the short term.

In production projects I like to use the value-object pattern, where I define data transfer objects for each entity and only use these objects as return types and parameters. I'm skipping over that part for the sake of clarity in this sample project—since there is only one entity in our domain. This is something you can add in later, after completing the steps to build the initial to-do list application.

Now we're ready to implement this service in the same package:

package org.epseelon.samples.todolist.business; import java.util.List; import org.epseelon.samples.todolist.domain.TodoItem; import org.epseelon.samples.todolist.domain.TodoItemRepository; public class TodoServiceImpl implements TodoService { private TodoItemRepository todoItemRepository; public void setTodoItemRepository(TodoItemRepository todoItemRepository) { this.todoItemRepository = todoItemRepository; } public TodoItem save(TodoItem item) throws Exception { try { this.todoItemRepository.save(item); return item; } catch (Exception e) { throw new Exception("Could not save item because: " + e.getCause()); } } public void remove(TodoItem item) throws Exception { try { this.todoItemRepository.remove(item); } catch (Exception e) { throw new Exception("Could not delete item because " + e.getMessage()); } } public TodoItem findById(TodoItem item) throws Exception { try { return this.todoItemRepository.findById(item); } catch (Exception e) { throw new Exception("Could not find item because " + e.getMessage()); } } public List<TodoItem> getList() throws Exception { try { return this.todoItemRepository.getList(); } catch (Exception e) { throw new Exception("Could not list items because " + e.getMessage()); } } }

As you can see, this implementation accesses a TodoItemRepository in package "org.epseelon.samples.todolist.domain". Here is the code used to create the interface:

package org.epseelon.samples.todolist.domain; import java.util.List; public interface TodoItemRepository { void remove(TodoItem todoItem); TodoItem save(TodoItem todoItem); TodoItem findById(TodoItem todoItem) throws Exception; List<TodoItem> getList(); }

This is its Hibernate-based implementation, in package "org.epseelon.samples.todolist.domain.hibernate":

package org.epseelon.samples.todolist.domain.hibernate; import java.util.List; import org.epseelon.samples.todolist.domain.TodoItem; import org.epseelon.samples.todolist.domain.TodoItemRepository; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class TodoItemHibernateDao extends HibernateDaoSupport implements TodoItemRepository { public TodoItem save(TodoItem todoItem) { getHibernateTemplate().saveOrUpdate(todoItem); return todoItem; } public void remove(TodoItem todoItem) { getHibernateTemplate().delete(todoItem); } public TodoItem findById(TodoItem todoItem) throws Exception { long id = todoItem.getId(); todoItem = (TodoItem) getHibernateTemplate().get(TodoItem.class, todoItem.getId()); if (todoItem == null) throw new Exception("Could not find an item with id " + id); return todoItem; } @SuppressWarnings("unchecked") public List<TodoItem> getList() { return (List<TodoItem>) getHibernateTemplate().loadAll(TodoItem.class); } }

And finally, the last piece of the Java puzzle is the code needed to create the org.epseelon.samples.todolist.domain.TodoItem class:

package org.epseelon.samples.todolist.domain; public class TodoItem { private long id; private String title; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }

The TodoItem class shown above is a standard implementation for returning the data from the repository.

Make sure to run 'mvn install' to ensure that the code compiles before moving on to the next section. In the next part, we'll configure the MySQL database and set up all of the pieces to work together.

Configuring the MySQL database

This section describes the setup of a MySQL database to store the application data. The first steps involve creating a todolist database and granting a user named "todolist" with the password "todolist" all rights to edit this database. After that is accomplished, we need to create one table in the todolist database.

Here is the DDL script to create the table:

CREATE TABLE `todoitem` ( `id_todoitem` int(10) unsigned NOT NULL auto_increment, `title` varchar(256) NOT NULL, PRIMARY KEY (`id_todoitem`) ) ENGINE=InnoDB;

Once you have created the table in the database, the next task is to configure the object-relational mapping for Hibernate. Create a TodoItem.hbm.xml file in src/main/java/org/epseelon/samples/todolist/domain/hibernate/hbm with the following content:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="org.epseelon.samples.todolist.domain.TodoItem" table="todoitem"> <id name="id" column="ID_TODOITEM" type="long"> <generator class="native" /> </id> <property name="title" column="TITLE" type="string" not-null="true" length="50" /> </class> </hibernate-mapping>

It is important to note that I could have used JPA annotations, rather than XML, but I prefer to work with XML so that is what I'm using for this sample project.

In order for the XML file to be included in our web application we need to add some configuration code to our POM. In the build element, add the following:

<resources> <resource> <directory>src/main/resources</directory> </resource> <resource> <directory>src/main/java</directory> <excludes> <exclude>**/*.java</exclude> </excludes> <includes> <include>**/*.xml</include> </includes> </resource> </resources>

At this point our entity is mapped. Now we can move on to the process for configuring Spring. Create a file named applicationContext.xml in src/main/webapp/WEB-INF that contains the following:

<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd"> <!-- Properties file --> <context:property-placeholder location="/WEB-INF/jdbc.properties"/> <!-- Datasource --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <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> <!-- Hibernate SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref local="dataSource"/> </property> <property name="mappingDirectoryLocations"> <list> <value> classpath:org/epseelon/samples/todolist/domain/hibernate/hbm/ </value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> ${hibernate.dialect} </prop> <prop key="hibernate.show_sql">true</prop> </props> </property> <property name="eventListeners"> <map> <entry key="merge"> <bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/> </entry> </map> </property> </bean> <!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= --> <bean id="todoService" class="org.epseelon.samples.todolist.business.TodoServiceImpl"> <property name="todoItemRepository" ref="todoItemRepository"/> </bean> <bean id="todoItemRepository" class="org.epseelon.samples.todolist.domain.hibernate.TodoItemHibernateDao"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- ========================= TRANSACTION MANAGEMENT ========================= --> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref local="sessionFactory"/> </property> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <!-- the transactional semantics... --> <tx:attributes> <!-- all methods starting with 'get' are read-only --> <tx:method name="get*" read-only="true"/> <!-- other methods use the default transaction settings (see below) --> <tx:method name="*"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="todoServiceOperation" expression="execution(* org.epseelon.samples.todolist.business.TodoService.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="todoServiceOperation"/> </aop:config> </beans>

I recommend taking the time to read through the code above, because it includes a couple of intriguing and powerful features available in Spring 2.5.

In the first line in the file above, we import properties from a properties file. Let's create that jdbc.properties file in src/main/webapp/WEB-INF and add the following to it:

jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/todolist jdbc.username=todolist jdbc.password=todolist hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

Getting back to applicationContext.xml explanation, we then configure the Hibernate session factory.

After that, we create the service beans: todoService and todoItemRepository. And then we configure everything needed to wrap the service calls in transactions.

Once again, I could have used annotations to configure the beans and their connections, but I don't like to set it up that way. One of the primary reasons I enjoy working with Spring is that it allows me to gather all the wiring configuration in one place. I prefer keeping the connections in an XML file rather than having to sort through Java files to see how everything is connected.

In order to make the application context load into the web application, we have to edit src/main/webapp/WEB-INF/web.xml, like this:

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>Todo List</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>

At this point we're still missing two things. The first part is to create a log4j.properties file in the src/main/webapp/WEB-INF directory, like this:

### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n # set root logger level to debug and its only appender to mtf log4j.rootLogger=INFO,development # only for development purposes log4j.appender.development=org.apache.log4j.ConsoleAppender log4j.appender.development.layout=org.apache.log4j.PatternLayout log4j.appender.development.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p [%t] (%F:%L) - %m%n log4j.logger.noModule=FATAL log4j.logger.org.springframework=WARN # Log JDBC bind parameter runtime arguments log4j.logger.org.hibernate.type=DEBUG

And finally, we need to put the JDBC connector driver on the classpath of the application. In other words, if you're using JBoss, you have to download mysql-connector-java-5.x.x.jar and place it in $JBOSS_HOME/server/default/lib. In Tomcat, I think you can place it directly in $TOMCAT_HOME/lib. Be aware that it is not a good practice in a production environment to add this connector to your module dependencies in order to bundle it with your application.

Testing the application

For this first test, we'll just make sure the sample application starts successfully. (Later, we'll check to ensure that services work). Run 'mvn install' on the root module and copy todolist-web/target/todolist-web.war to the deployment directory ($JBOSS_HOME/server/default/deploy for JBoss, $TOMCAT_HOME/webapps for Tomcat). Then start up your server and look at the log. If you don't see any error messages, then you've completed the steps of this section of the article series. If you do get an error message, double check that you've done everything as described in this article, and if the error persists, try Googling the error to see if you can troubleshoot the issue. If it remains unresolved, please contact me and include comments describing the error you are receiving.

Where to go from here

In the next part of this three-part article series, I'll cover the process for developing the Flex UI and describe how to plug it into our Spring back-end using BlazeDS. Stay tuned!

To get more information about working with Hibernate, see the following online resources:

  • Hibernate – open source project home page
  • Hibernate – Third party articles and tutorials

And be sure to visit the Flex Developer Center to learn more about developing Flex applications. You'll find the latest articles, tutorials and sample projects to get you started.

Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License

More Like This

  • Providing XML to controls with E4X
  • Flex quick start guide for HTML and PHP developers
  • Creating a basic CRUD application using Flex and PHP with Zend AMF
  • Building a data-driven Flex and Java application with WebORB for Java
  • DigiPri Widgets sales dashboard – Part 2: Setting up the server application
  • Using the Flash Builder database introspector with PHP
  • Flash Builder 4 and PHP – Part 1: Data-centric development
  • Flash Builder 4 and PHP – Part 2: Zend AMF and Flash Remoting
  • Flex 4, Java, Spring, and Hibernate in Flash Builder 4
  • Adobe Flex, BlazeDS, and Hibernate JPA on Tomcat and MySQL — Part 1: Putting it all together in a simple demo application

Tutorials & Samples

Tutorials

  • Flex mobile performance checklist
  • Flex and Maven with Flexmojos – Part 3: Journeyman
  • Migrating Flex 3 applications to Flex 4.5 – Part 4

Samples

  • Twitter Trends
  • Flex 4.5 reference applications
  • Mobile Trader Flex app on Android Market

Flex User Forum

More
07/25/2011 Flash Player Debug Issues - Safari 5.1 & Chrome 13
04/22/2012 Loader png - wrong color values in BitmapData
04/22/2012 HTTPService and crossdomain.xml doesn't work as expected
04/23/2012 Memory related crashes in Flex application

Flex Cookbook

More
04/06/2012 How to detect screen resize with a SkinnableComponent
02/29/2012 Embed Stage3D content inside Flex application components
02/15/2012 Custom WorkFlow Component
02/09/2012 Using Camera with a MediaContainer instead of VideoDisplay

Products

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • Mobile Apps
  • Photoshop
  • Touch Apps
  • Student and Teacher Editions

Solutions

  • Digital marketing
  • Digital media
  • Web Experience Management

Industries

  • Education
  • Financial services
  • Government

Help

  • Product help centers
  • Orders and returns
  • Downloading and installing
  • My Adobe

Learning

  • Adobe Developer Connection
  • Adobe TV
  • Training and certification
  • Forums
  • Design Center

Ways to buy

  • For personal and home office
  • For students, educators, and staff
  • For small and medium businesses
  • For businesses, schools, and government
  • Special offers

Downloads

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

Company

  • News room
  • Partner programs
  • Corporate social responsibility
  • Career opportunities
  • Investor Relations
  • Events
  • Legal
  • Security
  • Contact Adobe
Choose your region United States (Change)
Choose your region Close

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

Terms of Use | Privacy Policy and Cookies (Updated)

Ad Choices

Reviewed by TRUSTe: site privacy statement