Adobe
Products
Creative Suite
Photoshop Family
Acrobat Family
Flash Platform
Digital Marketing Suite
Digital Publishing Suite
More products
Solutions
Digital marketing solutions
Digital media solutions
Education
Financial services
Government
Web Experience Management
More solutions
Learning Help Downloads Company
Store
Adobe Store for home and home office
Education Store for students, educators, and staff
Business Store for small and medium businesses
Other ways to buy
Search
 
Info Sign in
Welcome,
My cart
My orders My Adobe
My Adobe
My orders
My information
My preferences
Sign out
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Adobe
Products Sections   Search  
Solutions Company
Help Learning
Sign in Welcome, My orders My Adobe
Qty:
Purchase requires verification of academic eligibility
Subtotal
Review and Checkout
Adobe Developer Connection / Flex Developer Center /

flex_hibernate

by Maik Schumacher

Maik Schumacher

Content

  • Installing the software
  • Setting up the database
  • Preparing the development environment
  • Building the application
  • Running and testing the application

Created

27 October 2008

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
BlazeDS Flex Flex Builder Hibernate Java MySQL Tomcat

Requirements

Prerequisite knowledge

Some working knowledge of Eclipse and the Adobe Flex Builder will be helpful to build the application. Some Java and Flex background will help as well, but even with no any Java or Flex background you can still build the application from the available source code.

User level

Beginning

Required products

  • BlazeDS (Download trial)

Sample files

  • flex_hibernate_sample.zip (10529 KB)

Additional Requirements

Adobe Flex Builder 3 Eclipse Plug-in

  • Try
  • Buy

Flex 3 SDK

  • Download

Eclipse

  • Learn more
  • Choose "Eclipse IDE for Java EE Developers".

Hibernate

  • Learn more
  • You'll need:
  • Hibernate Core 3.3.1
  • Hibernate Annotations 3.4.0 GA
  • Hibernate EntityManager 3.4.0 GA
  • Hibernate Validator 3.1.0

Apache Tomcat

  • Learn more

MySQL

  • Learn more

MySQL Connector/J

  • Learn more

Java Runtime Environment (JRE)

  • Learn more
  • Adobe Flex Builder ship with JRE 1.5.

This article demonstrates how to create and run a simple Flex application that is connected to a relational database using the Hibernate implementation of the Java Persistence Architecture (JPA). It guides you through all steps required to create and run a sample application including setup of the required software.

The Hibernate website says this about Java Persistence with Hibernate:

The Java Persistence API is the standard object/relational mapping and persistence management interface of the Java EE 5.0 platform. As part of the EJB 3.0 specification effort, it is supported by all major vendors of the Java industry.

Hibernate implements the Java Persistence object/relational mapping and persistence management interfaces with the Hibernate Annotations and Hibernate EntityManager modules, on top of the mature and powerful Hibernate Core.

The Hibernate modules can be stacked and combined as desired. You can use the Hibernate Java Persistence provider in any environment, Java SE 5.0 or Java EE 5.0. The Hibernate Java Persistence provider is fully certified and passes the Sun TCK (Technology Compatibility Kit).

The sample application makes use of the following software and technology:

  • Eclipse 3.4 Ganymede
  • Adobe Flex Builder 3.0.1
  • Adobe Flex SDK 3.1
  • BlazeDS 3.0.1.1755
  • MySQL 5.0.67
  • Hibernate 3.3.1
  • Apache Tomcat 6.0.18
  • Sun Java JRE 1.6.0_07

The application uses a Flex front end to perform the following tasks:

  • Create new data records to a database
  • Read data from a database
  • Update existing data in a database
  • Delete data from a database

The application uses BlazeDS, a server-based Java remoting and Web messaging technology that enables developers to connect to back-end distributed data and push data in real-time to Adobe Flex and Adobe AIR applications. BlazeDS is an open source product. BlazeDS contains configurable channels that transport the data between the client and server. This article uses the Remote Procedure Call (RPC) Services (also called Flash Remoting) and Action Message Format (AMF).

AMF is a binary format for data serialization/deserialization and remote method invocation. It improves performance by dramatically compressing the size of data transferred and parsing binary data into objects in memory far more efficiently than parsing XML data.

This article is written for Java and Flex developers who want to learn more about integrating Flex with Java or vice versa. It follows a very practical approach and guides the reader through all steps needed to create a simple Web application; it includes all the code and configuration settings that are required to deploy and launch the application.

Flex developers will get a better understanding of the back end where the Java code communicates with the database, and Java developers will get a better understanding of the Flex coding in the front end.

Installing the software

Before building the application, install the software listed in the Requirements section.

Eclipse and Adobe Flex Builder

First, download and install Eclipse, then install Adobe Flex Builder 3 as a plug-in into Eclipse. Because Flex Builder does not include the Java Development Tools, it is installed on Eclipse as a plug-in instead of the standalone version. For more information on installing Flex Builder 3, see Install Flex Builder Plug-in on Windows.

Tomcat

Extract the Tomcat Server file apache-tomcat-6.0.18.zip to the folder C:\ADC.

MySQL

Create a C:\ADC\mysql folder.

Extract mysql-noinstall-5.0.51b-win32.zip and mysql-connector-java-5.1.6.zip in C:\ADC\mysql.

Hibernate

Also extract the four Hibernate ZIP files to the c:\ADC\hibernate directory as shown below in Figure 1.

The extracted Hibernate files on the file system
Figure 1: The extracted Hibernate files on the file system

Setting up the database

Before you develop the application, you need to start MySQL and create a database. You can do this in Eclipse, but it is simple to do at the command prompt.

Start MySQL

To start MySQL, open a command prompt window and go to the MySQL directory where you extracted the database files.

cd C:\ADC\mysql\mysql-5.0.67-win32\bin

Execute this command to start the database server:

mysqld --console

Later, if you need to shut down MySQL, execute this command:

mysqladmin -u root shutdown

Create the database

To create the database, execute the following command at a command prompt while still in the C:\ADC\mysql\mysql-5.0.67-win32\bin directory:

mysqladmin -u root create consultant_db

The name of the newly created database is consultant_db. To verify the database has been successfully created, execute this command:

mysqlshow.exe -u root

After executing the command all databases are listed in the command prompt window. The database table will be generated by Hibernate from the Java bean when the application is run for the first time.

Preparing the development environment

To set up your development environment, begin by starting Flex Builder 3. When the Workspace Launcher dialog box appears (see Figure 2), enter the directory to use for your workspace. For example:

C:\ADC\Workspace
The Workspace Launcher
Figure 2: The Workspace Launcher

If the Welcome page (see Figure 3) is open when Flex Builder starts, close it and go to the workbench.

The Flex Builder welcome page
Figure 3: The Flex Builder welcome page

Optionally update the JRE

As an optional step, you can update the Java Runtime Environment (JRE) to the most recent version. This is not a necessary step; Adobe Flex Builder ships with JRE 1.5.0_11, which will work just as well with the sample application. To do this in Flex Builder, follow these steps:

  1. Choose Window > Preferences. On the left hand side of the Preferences dialog box click Java and then Installed JREs. Click Add to add a new JRE (see Figure 4).
Installed JREs
Figure 4: Installed JREs
  1. Select Standard VM and click Next (see Figure 5).
Selecting the JRE Type
Figure 5: Selecting the JRE Type
  1. Click on Directory and browse to the desired JRE directory (see Figure 6).
Add JRE Dialog
Figure 6: Add JRE Dialog
  1. Select the checkbox in front of the newly added JRE and click OK, then click OK again to close the Preferences dialog box (see Figure 7).
The newly installed JRE
Figure 7: The newly installed JRE

Create the server runtime environment in Eclipse

It helps to create the server runtime before you create the actual project so that you are prepared when the New Project wizard asks you to select a server. Choose Window > Preferences. Next, on the left hand side of the Preferences dialog box click Server then Runtime Environments. Click Add to add a new runtime (see Figure 8).

Server Runtime Environments
Figure 8: Server Runtime Environments

Expand Apache, select Apache Tomcat v6.0, and click Next (see Figure 9).

New Server Runtime Environment
Figure 9: New Server Runtime Environment

Click Browse, browse to the extracted Tomcat directory (in this case, c:\ADC\apache-tomcat-6.0.18), and then click Finish (see Figure 10).

New Tomcat Server
Figure 10: New Tomcat Server

Click OK to close the Preferences dialog box.

Create the server

To create a new server, right-click in the Servers view of the Java EE perspective and select New > Server. In the New Server dialog box, select Apache Tomcat v6.0 Server and click Next (see Figure 11).

Define the Tomcat Server
Figure 11: Define the Tomcat Server

For now, do not add or remove any projects (see Figure 12). You will add the Web application to the Tomcat server later. Click Finish.

Do not add add and remove projects in this step.
Figure 12: Do not add add and remove projects in this step.

Building the application

Now you are ready to start developing the actual application.

Create the Project

To create your project, switch to the Flex Development perspective and then choose File > New > Flex Project. In the New Flex Project wizard, type ADCDemo for the Project Name. Make sure that the application type is set to Web application, and select J2EE for the application server type. Because the application uses the remote object access service make sure LiveCycle Data Services is selected (this is necessary because you are using BlazeDS).

Finally, select Create combined Java/Flex project using WTP, so you have the Java and the Flex source in one single project (see Figure 13). Click Next.

New Flex Project wizard
Figure 13: New Flex Project wizard

On the next screen (see Figure 14) ensure the target runtime is set to Apache Tomcat v6.0. The Context root should already be set to ADCDemo. For the Flex War file, browse to the BlazeDS Web application archive (in this case C:\ADC\blazeds-bin-3.0.1.1755\blazeds.war).

New Flex Project server configuration
Figure 14: New Flex Project server configuration

On the next screen, verify the Main source folder, Main application file, and Output folder URL are as shown in Figure 15 and click Finish.

New Flex Project build paths
Figure 15: New Flex Project build paths

After Adobe Flex Builder generates the project, you can see the new project in the Flex Navigator view on the left hand side. The name of the project is ADCDemo and it contains the following folders:

  • .settings: Eclipse adds and maintains the project specific configuration here
  • bin-debug: Contains the compiled Flex application; updated each time the project is rebuilt
  • flex_libs: Contains SWC files used by the compiler.
  • flex_src: Holds the source code of the Flex files, usually .mxml and .as (ActionScript) files
  • html-template: A set of HTML templates that provide a basic wrapper for the flex application
  • src: Contains the Java source code and additional configuration files
  • WebContent: Contains items to be published to the server. The configuration files for BlazeDS are in the subfolder WEB-INF/flex

Note: The project setup looks a little different in the Project Explorer view as shown in Figure 16.

The initial Project skeleton
Figure 16: The initial Project skeleton

The new project wizard has added the relevant BlazeDS JAR files to the project's WebContent\WEB-INF\lib folder as shown in Figure 17.

The lib folder after Flex Builder has created the project
Figure 17: The lib folder after Flex Builder has created the project

Copy the Java libraries to the project

You will also need to copy a number of Java libraries (JAR files) to the lib folder of the project. These JAR files are required by the sample application to implement the following:

  • Hibernate JPA
  • connection to the MySQL database
  • application logging

Copy the following JAR files to the target folder (C:\ADC\Workspace\ADCDemo\WebContent\WEB-INF\lib):

C:\ADC\hibernate\hibernate-validator-3.1.0.GA\hibernate-validator.jar C:\ADC\hibernate\hibernate-entitymanager-3.4.0.GA\hibernate-entitymanager.jar C:\ADC\hibernate\hibernate-entitymanager-3.4.0.GA\lib\ejb3-persistence.jar C:\ADC\hibernate\hibernate-entitymanager-3.4.0.GA\lib\test\log4j.jar C:\ADC\hibernate\hibernate-entitymanager-3.4.0.GA\lib\test\slf4j-log4j12.jar C:\ADC\hibernate\hibernate-annotations-3.4.0.GA\hibernate-annotations.jar C:\ADC\hibernate\hibernate-annotations-3.4.0.GA\lib\hibernate-commons-annotations.jar C:\ADC\hibernate\hibernate-distribution-3.3.1.GA\hibernate3.jar C:\ADC\hibernate\hibernate-distribution-3.3.1.GA\lib\required\antlr-2.7.6.jar C:\ADC\hibernate\hibernate-distribution-3.3.1.GA\lib\required\commons-collections-3.1.jar C:\ADC\hibernate\hibernate-distribution-3.3.1.GA\lib\required\dom4j-1.6.1.jar C:\ADC\hibernate\hibernate-distribution-3.3.1.GA\lib\required\javassist-3.4.GA.jar C:\ADC\hibernate\hibernate-distribution-3.3.1.GA\lib\required\jta-1.1.jar C:\ADC\hibernate\hibernate-distribution-3.3.1.GA\lib\required\slf4j-api-1.4.2.jar C:\ADC\mysql\mysql-connector-java-5.1.6\mysql-connector-java-5.1.6-bin.jar

After you have copied the files, you should have 27 JAR files in the target directory. When you refresh the project in Flex Builder, the lib folder in the Project Explorer view should show them all (see Figure 18).

The lib folder in the Project Explorer view
Figure 18: The lib folder in the Project Explorer view

Change the context root in Flex properties

Initially the server's context root is not set properly after the project has been created. To change this either open the properties of the Flex project ADCDemo, select Flex Server and change the context root to /ADCDemo or change the serverContextRoot property in the file .flexProperties. To do this open the file .flexProperties in Flex Builder (you can find it in the Flex Navigator view in the root folder of the ADCDemo project) and change the property serverContextRoot to the context root of the Web application ("/ADCDemo"). Replace

serverContextRoot="/WebContent"

with

serverContextRoot="/ADCDemo"

Save and close the file.

Create the logging configuration file

The sample application uses the Apache log4j logging utility to log database access. You need an XML configuration file in the Java Source folder named log4j.xml to configure log4j. In the Java source folder create a new file and name it log4j.xml and copy the following code into it.

The source code and the XML files are included in the available ZIP file and the file content can be reused by copy and paste its content or by simply copy the file to the correct location on the file system.

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration debug="false" xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <param name="target" value="System.out" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p %-40.70C{6} %x - %m%n" /> </layout> </appender> <appender name="ADC_DEMO" class="org.apache.log4j.RollingFileAppender"> <!-- Change the log path and file name here! --> <param name="File" value="c:/ADC/logs/adc.log" /> <param name="Append" value="true" /> <param name="MaxFileSize" value="2MB" /> <param name="MaxBackupIndex" value="8" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p %-40.70C{6} %x - %m%n" /></layout> </appender> <appender name="LOG_APACHE" class="org.apache.log4j.RollingFileAppender"> <!-- Change the log path and file name here! --> <param name="File" value="c:/ADC/logs/apache.log" /> <param name="Append" value="true" /> <param name="MaxFileSize" value="2MB" /> <param name="MaxBackupIndex" value="8" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p %-40.70C{6} %x - %m%n" /> </layout> </appender> <logger name="com.adobe" additivity="false"> <level value="DEBUG" /> <appender-ref ref="ADC_DEMO" /> <appender-ref ref="STDOUT" /> </logger> <!-- Hibernate --> <logger name="org.hibernate"> <level value="WARN" /> </logger> <!-- Apache Commons --> <logger name="org.apache.commons"> <level value="INFO" /> <appender-ref ref="LOG_APACHE" /> <appender-ref ref="STDOUT" /> </logger> <!-- Apache Jasper --> <logger name="org.apache.jasper"> <level value="INFO" /> <appender-ref ref="LOG_APACHE" /> <appender-ref ref="STDOUT" /> </logger> <!-- Apache Catalina --> <logger name="org.apache.catalina"> <level value="INFO" /> <appender-ref ref="LOG_APACHE" /> <appender-ref ref="STDOUT" /> </logger> <!-- Apache Coyote --> <logger name="org.apache.coyote"> <level value="INFO" /> <appender-ref ref="LOG_APACHE" /> <appender-ref ref="STDOUT" /> </logger> <logger name="net"> <level value="WARN" /> <appender-ref ref="ADC_DEMO" /> <appender-ref ref="STDOUT" /> </logger> <!-- DEFAULT: All log message are send to Appender ADC_DEMO and STDOUT. Log Level Order: DEBUG, INFO, WARN, ERROR, FATAL --> <root> <priority value="DEBUG" /> <appender-ref ref="STDOUT" /> <appender-ref ref="ADC_DEMO" /> </root> </log4j:configuration>

Save and close the file. When you run the application log4j will create a new directory called logs in the directory c:\ADC and add two log files to it.

Create the JPA persistence configuration file

When using the JPA implementation of Hibernate you need to configure the entity beans. This is done with an XML configuration file called persistence.xml, which is a standard configuration file in JPA. It has to be included in the META-INF directory inside the classpath of the project or in a JAR file that contains the entity beans. The persistence.xml file must define a persistence-unit with a unique name in the current scoped classloader.

Create a new folder in the Java Source folder and name it META-INF. Create a new file in this folder, name it persistence.xml, and copy the following code into the file:

<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="consultant_db"> <properties> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> <property name="hibernate.connection.url" value="jdbc:mysql://localhost/consultant_db" /> <property name="hibernate.connection.username" value="root" /> <property name="hibernate.connection.password" value="" /> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> <property name="hibernate.connection.pool_size" value="6" /> <property name="hibernate.connection.autoReconnect" value="true" /> <property name="hibernate.generate_statistics" value="false" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.use_sql_comments" value="false" /> <property name="hibernate.hbm2ddl.auto" value="update" /> </properties> </persistence-unit> </persistence>

The persistence configuration must hold a persistence-unit node. In this case, the name is consultant_db. This name is used by the JPA EntityManager later to access the database described by the properties of the persistence-unit node.

Create the Java code

Create a new Java package beneath the Java source folder and name it com.adobe.demo. In the newly created package create a new Java class and name it Consultant (see Figure 19). The Consultant class is the entity bean that defines the structure of an object Consultant. It also contains the annotations (a special form of syntactic metadata) that describe the database relation (here the table including its columns) and some SQL queries.

Project Explorer after creating the Java bean
Figure 19: Project Explorer after creating the Java bean

Copy the following code to the Java class Consultant (Consultant.java).

package com.adobe.demo; import java.sql.Timestamp; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; import org.hibernate.annotations.Index; @Entity @Table(name = "consultants") @NamedQueries( { @NamedQuery(name = "consultants.findAll", query = "from Consultant"), @NamedQuery(name = "consultants.byId", query = "select c from Consultant c where c.consultantId= :consultantId") }) public class Consultant { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "consultantId", nullable = false) private Long consultantId; @Basic @Index(name = "ldapName_idx_1") @Column(name = "ldapName", nullable = true, unique = true) private String ldapName; @Basic @Column(name = "firstName", nullable = true, unique = false) private String firstName; @Basic @Column(name = "lastName", nullable = true, unique = false) private String lastName; @Basic @Column(name = "title", nullable = true, unique = false) private String title; @Basic @Column(name = "created", nullable = false, unique = false) private Timestamp created; public Consultant() { super(); } public Long getConsultantId() { return consultantId; } public void setConsultantId(Long consultantId) { this.consultantId = consultantId; } public String getLdapName() { return ldapName; } public void setLdapName(String ldapName) { this.ldapName = ldapName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Timestamp getCreated() { return created; } public void setCreated(Timestamp created) { this.created = created; } }

In the code above, the annotation @Table holds the name of the database table ("consultants") that will be created when the application runs the first time.

Next create the service class that contains the business methods of the demo application. Create a new class named ConsultantService in the package com.adobe.demo. This class contains those methods that are later consumed by the Flex application:

  • getConsultants: Retrieves all rows from the database table consultants.
  • addUpdateConsultant: Adds or updates a consultant records into the database.
  • deleteConsultant: Deletes a database record from the database.

Copy the following code to the Java class ConsultantService (ConsultantService.java).

package com.adobe.demo; import java.sql.Timestamp; import java.util.Date; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; import javax.persistence.Query; import org.apache.log4j.Logger; public class ConsultantService { private static final String PERSISTENCE_UNIT = "consultant_db"; private static Logger logger = Logger.getLogger(ConsultantService.class); public ConsultantService() { super(); } public List<Consultant> getConsultants() { logger.debug("** getConsultants called..."); EntityManagerFactory entityManagerFactory = Persistence .createEntityManagerFactory(PERSISTENCE_UNIT); EntityManager em = entityManagerFactory.createEntityManager(); Query findAllQuery = em.createNamedQuery("consultants.findAll"); List<Consultant> consultants = findAllQuery.getResultList(); if (consultants != null) logger.debug("** Found " + consultants.size() + "records:"); return consultants; } public void addUpdateConsultant(Consultant consultant) throws Exception { logger.debug("** addUpdateConsultant called..."); EntityManagerFactory emf = Persistence .createEntityManagerFactory(PERSISTENCE_UNIT); EntityManager em = emf.createEntityManager(); // When passing Boolean and Number values from the Flash client to a // Java object, Java interprets null values as the default values for // primitive types; for example, 0 for double, float, long, int, short, // byte. if (consultant.getConsultantId() == null || consultant.getConsultantId() == 0) { // New consultant is created consultant.setConsultantId(null); consultant.setCreated(new Timestamp(new Date().getTime())); } else { // Existing consultant is updated - do nothing. } EntityTransaction tx = em.getTransaction(); tx.begin(); try { em.merge(consultant); tx.commit(); } catch (Exception e) { logger.error("** Error: " + e.getMessage()); tx.rollback(); throw new Exception(e.getMessage()); } finally { logger.info("** Closing Entity Manager."); em.close(); } } public void deleteConsultant(Long consultantId) { logger.debug("** deleteConsultant called..."); EntityManagerFactory emf = Persistence .createEntityManagerFactory(PERSISTENCE_UNIT); EntityManager em = emf.createEntityManager(); Query q = em.createNamedQuery("consultants.byId"); q.setParameter("consultantId", consultantId); Consultant consultant = (Consultant) q.getSingleResult(); if (consultant != null) { EntityTransaction tx = em.getTransaction(); tx.begin(); try { em.remove(consultant); tx.commit(); } catch (Exception e) { logger.error("** Error: " + e.getMessage()); tx.rollback(); } finally { logger.info("** Closing Entity Manager."); em.close(); } } } }

BlazeDS server-side configuration

On the sever side you need to extend a BlazeDS configuration file to enable the Java service to be accessed later from the Flex client. Open the remoting-config.xml file in the project folder WebContent/WEB-INF/flex and overwrite the content with the following:

<?xml version="1.0" encoding="UTF-8"?> <service id="remoting-service" class="flex.messaging.services.RemotingService"> <adapters> <adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true" /> </adapters> <default-channels> <channel ref="my-amf" /> </default-channels> <!-- ADC Demo application --> <destination id="consultantService"> <properties> <source>com.adobe.demo.ConsultantService </source> </properties> </destination> </service>

This adds a new destination block that is identified by the id consultantService and that is linked to the Java service class ConsultantService.

Create the Flex code

A detailed explanation of the Flex view files is beyond the scope of this article. Adobe Flex Builder provides an integrated help system that explains all aspects of Adobe Flex 3.

To add the Flex code to the flex-src folder of the Flex project, switch to the Flex perspective and create a new hierarchical folder structure in the flex-src folder similar to the Java package as shown in Figure 20.

The structure in the Flex source folder
Figure 20: The structure in the Flex source folder

Copy the following code to the existing MXML file ADCDemo.mxml. This is the main application that loads the view ListConsultants that is created a few steps later.

<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:view="com.adobe.demo.view.*" backgroundColor="#FFFFFF"> <view:ListConsultants id="listConsultants" /> </mx:Application>

In the vo (value object) folder, create a new ActionScript class and name it Consultant.as. This class defines the client object that holds the consultant information. Please note that the class refers to the appropriate Java class Consultants. Copy the following content to the ActionScript class.

package com.adobe.demo.vo { [Bindable] [RemoteClass(alias="com.adobe.demo.Consultant")] public class Consultant { public function Consultant() { } public var consultantId:Number; public var ldapName:String; public var firstName:String; public var lastName:String; public var title:String; public var created:Date; } }

The next MXML file is more complex. In the view folder of the Flex source folder, create a file named ListConsultants.mxml and copy the following code into it.

<?xml version="1.0" encoding="utf-8"?> <mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:view="com.adobe.demo.view.*" width="100%" height="100%" title="Adobe Demo - Found {consultantRecords} consultants." creationComplete="loadConsultants();"> <mx:RemoteObject id="loaderService" destination="consultantService" result="handleLoadResult(event)" fault="handleFault(event)" showBusyCursor="true" /> <mx:RemoteObject id="deleteService" destination="consultantService" result="handleDeleteResult(event)" fault="handleFault(event)" showBusyCursor="true" /> <mx:Script> <![CDATA[ import com.adobe.demo.vo.Consultant; import mx.controls.Alert; import mx.managers.PopUpManager; import mx.containers.TitleWindow; import mx.collections.ArrayCollection; import mx.rpc.events.ResultEvent; import mx.rpc.events.FaultEvent; [Bindable] private var message:String; [Bindable] private var consultants:ArrayCollection = new ArrayCollection(); [Bindable] private var consultantRecords:int = 0; public function loadConsultants():void { loaderService.getConsultants(); } private function deleteConsultant():void { if(dataGrid.selectedItem != null) { var selectedItem:Consultant = dataGrid.selectedItem as Consultant; deleteService.deleteConsultant(selectedItem.consultantId); } } private function createConsultant():void { var titleWindow:ConsultantForm = ConsultantForm(PopUpManager.createPopUp(this, ConsultantForm, true)); titleWindow.setStyle("borderAlpha", 0.9); titleWindow.formIsEmpty = true; } private function updateConsultant():void { var titleWindow:ConsultantForm = ConsultantForm(PopUpManager.createPopUp(this, ConsultantForm, true)); titleWindow.setStyle("borderAlpha", 0.9); titleWindow.consultant = dataGrid.selectedItem as Consultant; titleWindow.formIsEmpty = false; } private function handleLoadResult(ev:ResultEvent):void { consultants = ev.result as ArrayCollection; consultantRecords = consultants.length; } private function handleDeleteResult(ev:ResultEvent):void { Alert.show("The consultant has been deleted.", "Information", Alert.OK, null, null, null, Alert.OK); loadConsultants(); } private function handleFault(ev:FaultEvent):void { message = "Error: " + ev.fault.faultCode + " - " + ev.fault.faultDetail + " - " + ev.fault.faultString; } ]]> </mx:Script> <mx:VBox width="100%" height="100%"> <mx:Label text="{message}" fontWeight="bold" includeInLayout="false" /> <mx:DataGrid id="dataGrid" width="100%" height="100%" dataProvider="{consultants}" doubleClickEnabled="true" doubleClick="updateConsultant()" > <mx:columns> <mx:DataGridColumn dataField="consultantId" headerText="Consultant ID" width="100"/> <mx:DataGridColumn dataField="ldapName" headerText="LDAP Name" /> <mx:DataGridColumn dataField="firstName" headerText="First Name" /> <mx:DataGridColumn dataField="lastName" headerText="Last Name" /> <mx:DataGridColumn dataField="title" headerText="Title" /> <mx:DataGridColumn dataField="created" headerText="Creation Date" /> </mx:columns> </mx:DataGrid> <mx:ControlBar horizontalAlign="center"> <mx:Button label="Create Consultant" click="createConsultant()" toolTip="Create a new consultant and store it in the database." /> <mx:Button label="Update Consultant" click="updateConsultant()" enabled="{dataGrid.selectedItem}" toolTip="Update an existing database consultant." /> <mx:Button label="Delete Consultant" click="deleteConsultant()" enabled="{dataGrid.selectedItem}" toolTip="Delete the consultant from the database." /> <mx:Button label="Reload Data" click="loadConsultants()" toolTip="Reload the consultant list from the database." /> </mx:ControlBar> </mx:VBox> </mx:Panel>

The mx:RemoteObject tags contain an id attribute and a destination attribute that is set to consultantService. This is the link to the service defined in remoting-config.xml, which in turn is linked to the appropriate Java service. This is basically the client-side configuration of the service. The Java service methods are called by referring to the id of the remote object followed by the method name of the Java service class. For example, here is the Java method getConsultants called using this command:

loaderService.getConsultants();

In the same view folder, create a file named ConsultantForm.mxml and copy the following code into it. This file represents the Flex view to create and update a consultant data record and it also contains actions to validate the data.

<?xml version="1.0" encoding="utf-8"?> <mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:vo="com.adobe.demo.vo.*" width="100%" height="100%" defaultButton="{submitButton}" showCloseButton="true" creationComplete="creationCompleteHandler();" close="PopUpManager.removePopUp(this);" title="Consultant Form" xmlns:text="flash.text.*"> <mx:RemoteObject id="saveService" destination="consultantService" result="handleSaveResult(event)" fault="handleFault(event)" showBusyCursor="true" /> <vo:Consultant id="consultant" ldapName="{ldapNameField.text}" firstName="{firstNameField.text}" lastName="{lastNameField.text}" title="{titleField.text}" /> <mx:Script> <![CDATA[ import mx.managers.PopUpManager; import mx.controls.Alert; import mx.containers.Canvas; import mx.rpc.events.ResultEvent; import mx.rpc.events.FaultEvent; import mx.events.ValidationResultEvent; import mx.validators.Validator; [Bindable] private var message:String; [Bindable] private var formIsValid:Boolean = false; [Bindable] public var formIsEmpty:Boolean; // Holds a reference to the currently focussed control on the form. private var focussedFormControl:DisplayObject; private function handleSaveResult(ev:ResultEvent):void { clearFormHandler(); validateForm(ev); Alert.show("Consultant successfully created/updated.", "Information", Alert.OK, null, null, null, Alert.OK); // Reload the list. parentApplication.listConsultants.loaderService.getConsultants(); PopUpManager.removePopUp(this); } private function handleFault(ev:FaultEvent):void { message = "Error: " + ev.fault.faultCode + " \n " + "Detail: " + ev.fault.faultDetail + " \n " + "Message: " + ev.fault.faultString; } public function saveConsultant():void { saveService.addUpdateConsultant(consultant); } private function creationCompleteHandler():void { PopUpManager.centerPopUp(this); resetFocus(); } private function resetFocus():void { focusManager.setFocus(ldapNameField); } // Validate the form public function validateForm(event:Event):void { focussedFormControl = event.target as DisplayObject; formIsValid = true; // Check if form is empty formIsEmpty = (ldapNameField.text == "" && firstNameField.text == "" && firstNameField.text == ""); validate(ldapNameValidator); validate(firstNameValidator); validate(lastNameValidator); } private function validate(validator:Validator):Boolean { // See also here for validating data: // /devnet/flex/quickstart/validating_data/ var validatorSource:DisplayObject = validator.source as DisplayObject; var suppressEvents:Boolean = (validatorSource != focussedFormControl); var event:ValidationResultEvent = validator.validate(null, suppressEvents); var currentControlIsValid:Boolean = (event.type == ValidationResultEvent.VALID); formIsValid = formIsValid && currentControlIsValid; return currentControlIsValid; } private function clearFormHandler():void { // Clear all input fields. ldapNameField.text = ""; firstNameField.text = ""; lastNameField.text = ""; message = ""; // Clear validation error messages. ldapNameField.errorString = ""; firstNameField.errorString = ""; lastNameField.errorString = ""; formIsEmpty = true; formIsValid = false; resetFocus(); } ]]> </mx:Script> <mx:StringValidator id="ldapNameValidator" source="{ldapNameField}" property="text" minLength="2" required="true" /> <mx:StringValidator id="firstNameValidator" source="{firstNameField}" property="text" minLength="2" required="true" /> <mx:StringValidator id="lastNameValidator" source="{lastNameField}" property="text" minLength="2" required="true" /> <mx:Form> <mx:FormItem label="LDAP Name" required="true"> <mx:TextInput id="ldapNameField" text="{consultant.ldapName}" change="validateForm(event);" /> </mx:FormItem> <mx:FormItem label="First Name" required="true"> <mx:TextInput id="firstNameField" text="{consultant.firstName}" change="validateForm(event);" /> </mx:FormItem> <mx:FormItem label="Last Name" required="true"> <mx:TextInput id="lastNameField" text="{consultant.lastName}" change="validateForm(event);" /> </mx:FormItem> <mx:FormItem label="Title" required="false"> <mx:TextInput id="titleField" text="{consultant.title}" /> </mx:FormItem> </mx:Form> <mx:ControlBar horizontalAlign="center"> <mx:Button label="Save Consultant" id="submitButton" enabled="{formIsValid}" click="saveConsultant();" /> <mx:Button label="Clear form" enabled="{!formIsEmpty}" click="clearFormHandler();" /> <mx:Button label="Cancel" click="PopUpManager.removePopUp(this);"/> </mx:ControlBar> <mx:Spacer height="10" /> <mx:Text text="{message}" fontWeight="bold" width="300" /> </mx:TitleWindow>

Running and testing the application

Finally you are done setting up the infrastructure and creating the sample application. Now you can run the application on the Tomcat server and test it in a Web browser.

In the Java EE perspective of Eclipse right click on Tomcat v6.0 Server in the Server view and select Add and Remove Projects. In the Add and Remove Projects dialog box select the Web application ADCDemo from the list of available projects and click Add; then click Finish.

Add the demo application to the Tomcat server
Figure 21: Add the demo application to the Tomcat server

Click the Start the Server button in the Server view and verify the state of the server is "Started". Alternatively, consult the Console view of Eclipse, and look for a message that indicates the server is started, for example:

INFO: Server startup in 5443 ms

Open a Web browser and enter the following URL to access the sample application:

http://localhost:8080/ADCDemo/ADCDemo.html

It takes a few seconds to generate the database table. Figure 22 shows the application running for the first time.

The sample application running the first time
Figure 22: The sample application running the first time

To create a new consultant record, click Create Consultant and enter the appropriate data. Click Save Consultant to close the window and refresh the data list. The newly created record is then displayed (see Figure 23). You can then add more data records, update existing data records (see Figure 24), and delete data records.

The sample application after adding a consultant
Figure 23: The sample application after adding a consultant
Updating a data record
Figure 24: Updating a data record

Where to go from here

In this article you learned how to build and test a Flex application that connects to a relational database using the Hibernate implementation of the Java Persistence Architecture.

In Part 2 of the series, you'll extend the demo to use linked database relations.

To get a deeper understanding of the technologies used, explore some of the following references:

  • Adobe Flex 3 Online Help
  • BlazeDS
  • BlazeDS Developer Guide
  • Hibernate Documentation Overview
  • Java Persistence with Hibernate
  • MySQL 5.0 Reference Manual

More Like This

  • Creating a basic CRUD application using Flex and PHP with Zend AMF
  • Using the Flash Builder database introspector with PHP
  • Building a data-driven Flex and Java application with WebORB for Java
  • Accessing EJBs in Flex with Oracle WebLogic and BlazeDS
  • Dependency injection with Flex
  • Flex and Java differences: Getters and setters
  • Flex, BlazeDS, and Hibernate JPA on Tomcat and MySQL – Part 2: Extending the demo to use linked database relations
  • The Flex, Spring and BlazeDS full stack – Part 2: Writing the to-do list server
  • The Flex, Spring and BlazeDS full stack – Part 3: Putting the application together
  • The Flex, Spring, and BlazeDS full stack – Part 1: Creating a Flex module

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
02/08/2012 Localising Flex Validators
02/10/2012 Pass Http Header information to a Flex application
02/09/2012 Global Event Listeners for all Views in a ViewNavigatorApplication
01/24/2008 Is Stacked Bar/Column chart Supports Multiseries..?

Flex Cookbook

More
02/09/2012 Using Camera with a MediaContainer instead of VideoDisplay
02/08/2012 Digital Clock
01/20/2012 Skinnable Transform Tool
12/12/2011 Date calculations using 'out-of-the-box' functions

Products

  • Creative Suite
  • Photoshop Family
  • Acrobat Family
  • Flash Platform
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Mobile apps

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

  • Adobe Store
  • For students and educators
  • For small and medium businesses
  • For enterprises
  • 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
  • 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
  • Pacific - English
  • 台灣

Southeast Asia

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

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy (updated 07-14-2009).

Ad Choices

Reviewed by TRUSTe: site privacy statement