My First Hibernate Enabled Flex Application

In this tutorial, we are going to create an employee management console using Flex Data Services 2 which uses Hibernate 3 to communicate with a MySQL database. In this console, we will be able to add, delete and edit employees found in the database.

edit-vew.jpg

This tutorial is intended for new users of Flex Data Services 2 as well as Hibernate. However, it is assumed that you have working knowledge of Java, MySQL  and J2EE based web application creation and deployment.


You will need the following packages :

Hibernate 3 is provided with Flex Data Services 2 located in the resources folder.

Part 1 – Setting up our sample database
As mentioned above, we will be using MySQL as the database for this tutorial. Most samples use HSQL, but let’s be different.

1.1 Install MySQL: Follow the installation instructions for MySQL Database Engine posted on the MySQL site. Once the database server is installed and running on your machine, we need to create the sample database and insert some sample data to be used in our application.

1.2 Create the database: Copy and paste the following SQL code into a text file named employee.sql

CREATE DATABASE SampleDB;
USE SampleDB;

DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
  `employeeid` int(10) unsigned NOT NULL auto_increment,
  `firstname` varchar(255) default NULL,
  `lastname` varchar(255) default NULL,
  PRIMARY KEY  (`employeeid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `employee` (`employeeid`,`firstname`,`lastname`) VALUES
 (1,’Conrad’,’Simms’),
 (2,’Akira’,’Tanaka’),
 (3,’Rye’,’Woodard’);

From a command prompt, navigate to the bin directory located in the MySQL root folder (i.e. c:\mysql\bin) and execute the following command:

                mysql  -user=root < some_path_here\employee.sql

You will now have a database named SampleDB that contains a table named employee. This table now contains three records of data.

Part 2 – Setting up our project There are several approaches for deploying Flex applications, for the purposes of this tutorial; we will deploy our application within the existing Flex web application already made available in the Integrated Flex Server that gets installed with Flex Data Services 2. To read more about other deployment options, read the Deploying Flex Applications section in the documentation.

2.1 Install Flex Data Services 2: If you have not already done so, install Flex Data Services 2. During the install procedure, choose to install the Integrated Flex Server option.The root of our application will then be C:\fds2\jrun4\servers\default\flex

2.2 Build the persistent class:
In it’s simplest form, building a hibernate application consists of a hibernate configuration file, a database table mapping file and a persistent class which represents that table. For detailed information on Hibernate, visit http://www.hibernate.org.We are going to start with the persistent class. This class needs to expose fields that correspond with the columns in the database table. Let’s refresh our memories on the table structure:      

employeeid (int)
firstname(varchar)
lastname(varchar)

So, we’ll need a java class that will expose these data elements. It is recommended to follow the JavaBean standard of setters and getters. In the following sample, you will notice that the employeeid column is replaced by an id field in the java class. This is because Hibernate requires a field called id so that it can manage the unique identifier for the object.Create a file named Employee.java in the following location:

c:\fds2\jrun4\servers\default\flex\WEB-INF\src\EmployeeManagement

Here is the contents of the Employee.java class:

package EmployeeManagement;
       public class Employee {
              private int id;
              private String firstname;
              private String lastname;
              public void setId(int id)
              {
                     this.id = id;
              }              public int getId()
              {
                     return this.id;
              }
      
              public void setFirstname(String firstname)
              {
                     this.firstname = firstname;
              }              public String getFirstname()
              {
                     return firstname;
              }
      
              public void setLastname(String lastname)
              {
                     this.lastname = lastname;
              }
             
              public String getLastname()
              {
                     return lastname;
              }
       }

 

The next step is to compile this file:

javac Employee.java

This will result in a file named Employee.class in the same folder. We need to copy the class file into our application. First, create a folder called EmployeeManagement.

mkdir C:\fds2\jrun4\servers\default\flex\WEB-INF\classes\EmployeeManagement

Now copy the Employee.class file to:

copy Employee.class C:\fds2\jrun4\servers\default\flex\WEB-INF\classes\EmployeeManagement

2.3 Creating the mapping file: We now need to create the Hibernate mapping file that will tell Hibernate which columns in the database map to the persistent class we just created. The following is the mapping for this tutorial:<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
              "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">       <hibernate-mapping>
           <class name="EmployeeManagement.Employee" table="employee">
                     <id name="id" column="employeeid">
                     <generator class="native"/>
                     </id>
                     <property name="firstname"/>
                     <property name="lastname"/>
            </class>
       <!– This is a named query that we will use later –>   
       <query name="all.employees">From Employee</query>
</hibernate-mapping>

      

Save this file as Employee.hbm.xml in the same folder where we just placed our persistent class:

C:\fds2\jrun4\servers\default\flex\WEB-INF\classes\EmployeeManagement

2.4 Creating the Hibernate configuration file:  This file contains the configuration settings that will enable Hibernate to connect to the database that we would like to access. The following Hibernate configuration contains the minimal settings required for this tutorial to work:

<?xml version=’1.0′ encoding=’utf-8’?>

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>

        <!– Database connection settings –>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost/SampleDB</property>
        <property name="connection.username">root</property>
        <property name="connection.password"></property>

        <!– JDBC connection pool (use the built-in) –>
        <property name="connection.pool_size">1</property>

        <!– SQL dialect –>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!– Enable Hibernate’s automatic session context management –>
        <property name="current_session_context_class">thread</property>

        <!– Disable the second-level cache  –>
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>        <!– Echo all executed SQL to stdout –>
        <property name="show_sql">true</property>

        <!– Load the database table mapping file –>
        <mapping resource="EmployeeManagement/Employee.hbm.xml"/>

    </session-factory>

</hibernate-configuration>

This file must be named hibernate.cfg.xml and must be in the application’s classpath. Therefore, we will save this file in the following location:

C:\fds2\jrun4\servers\default\flex\WEB-INF\classes

2.5 Adding a data services destination:  The next step in this section is to add a data service destination in the Flex Data Services 2 configuration. In addition to adding a destination that will use the Flex Hibernate adapter. We need to configure a default channel. To do this, we must edit the data-management-config.xml file located here:

C:\fds2\jrun4\servers\default\flex\WEB-INF\flex

By default, the contents of this file looks like this:

       <?xml version="1.0" encoding="UTF-8"?>
       <service id="data-service"
              class="flex.data.DataService"
              messageTypes="flex.data.messages.DataMessage">

       <adapters>
        <adapter-definition id="actionscript" class="flex.data.adapters.ASObjectAdapter" default="true"/>
        <adapter-definition id="java-dao" class="flex.data.adapters.JavaAdapter"/>
       </adapters>

       </service>

Let’s add the default channel:<?xml version="1.0" encoding="UTF-8"?>
  

    

<service id="data-service"
              class="flex.data.DataService"
              messageTypes="flex.data.messages.DataMessage">

       <adapters>
       <adapter-definition id="actionscript" class="flex.data.adapters.ASObjectAdapter" default="true"/>
        <adapter-definition id="java-dao" class="flex.data.adapters.JavaAdapter"/>
       </adapters>

       <default-channels>
                     <channel ref="my-rtmp"/>
       </default-channels>

       </service>

Next, add our Hibernate destination

<?xml version="1.0" encoding="UTF-8"?>
       <service id="data-service"
              class="flex.data.DataService"
              messageTypes="flex.data.messages.DataMessage">       <adapters>
                     <adapter-definition id="actionscript" class="flex.data.adapters.ASObjectAdapter" default="true"/>
              <adapter-definition id="java-dao" class="flex.data.adapters.JavaAdapter"/>
       </adapters>

       <default-channels>
                     <channel ref="my-rtmp"/>
       </default-channels>

   <destination id="employee.hibernate">
        <adapter ref="java-dao" />
        <properties>
            <use-transactions>true</use-transactions>
            <source>flex.data.assemblers.HibernateAssembler</source>
            <scope>application</scope>
            <metadata>
       <!–This is the unique identifier from the hibernate-entity bean –>
                <identity property="id"/>
            </metadata>
            <network>
                <session-timeout>20</session-timeout>
                <paging enabled="false" pageSize="10" />
                <throttle-inbound policy="ERROR" max-frequency="500"/>
                <throttle-outbound policy="REPLACE" max-frequency="500"/>
            </network>
            <server>
                <hibernate-entity>EmployeeManagement.Employee</hibernate-entity>
                <fill-method>
                    <name>fill</name>
                    <params>java.util.List</params>
                </fill-method>
                <fill-configuration>
                    <use-query-cache>false</use-query-cache>
                    <allow-hql-queries>true</allow-hql-queries>
                </fill-configuration>
            </server>
        </properties>
    </destination>

   </service>

 

2.6 Adding dependant jars: Finally, we must ensure that the Hibernate engine and supporting jars are included in our web application. We will need to get jars from two separate packages: MySQL Connector/J and Hibernate. If you have not already done so, download these packages from the urls provided at the beginning of this tutorial.From the MySQL Connector/J distrubution, copy the mysql-connector-java-3.0.15-ga-bin.jar to

C:\fds2\jrun4\servers\default\flex\WEB-INF\lib

From the Flex Data Services 2, navigate to the resources/hibernate folder, copy all of the jars from that folder to the same location as the MySQL driver you just copied. Part 3 – Building the Flex Application Now that we have Hibernate and Flex Data Services configured and ready, it’s time to create a Flex application that will consume those services.First, we will create a directory to contain our Flex application. And then a sub-directory that will contain our ActionScript class.

       mkdir C:\fds2\jrun4\servers\default\flex\EmployeeManager
       mkdir C:\fds2\jrun4\servers\default\flex\EmployeeManager\EmployeeManagement

3.1 Create our ActionScript class: We need to create an ActionScript class that represents the the persistent java class we created earlier. This is the bridge between our Flex application and our Hibernate object. This will be a managed class that will be linked to our remote java persistent class.

package EmployeeManagement
       {
              [Managed]
              [RemoteClass(alias="EmployeeManagement.Employee")]
              public class Employee
              {
                     public function Employee() {}
                    
                     public var id:int;
                     public var firstname:String="";
                     public var lastname:String="";
              }
       }

 

Save this file as Employee.as in :

C:\fds2\jrun4\servers\default\flex\EmployeeManager\EmployeeManagement

3.2 Create our base MXML Application: For starters, we will create an MXML application that simply displays all of the data from the database in a datagrid control.Let’s start with a base MXML file and add a data service tag that links the employee.hibernate destination that we defined previously in section 2.5.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

       <mx:DataService id="hibernate" destination="employee.hibernate" fault="handleFault(event)" autoCommit="true" /></mx:Application>

Create an ActionScript function that will invoke the fill method in defined in our destination. Notice that we are calling the named query “all.employees” we defined in the mapping file from section 2.3. The fill method returns an array of Employee objects. Also, we will define an ArrayCollection to hold the list of Employee objects. We also invoke the getEmployees() function  using the creationComplete event. The getEmployees() function will be called as soon as the application has been initialized and will immediately populate the ArrayList with the Employees returned from the database.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete=”getEmployees()”><mx:Script>
              <![CDATA[
                     import mx.controls.Alert;
                     import mx.rpc.events.FaultEvent;
                     import mx.collections.ArrayCollection;
                     import flash.events.MouseEvent;
                     import mx.rpc.AsyncToken;
                     import mx.data.*;
                     import EmployeeManagement.*;
                              
                     [Bindable]
                     private var EmployeeManagement:Employee;
                    
                     private function getEmployees():void {
                            currentState=”;
                            hibernate.fill(myArray,"all.employees",[]);

                     }
                    
                     private function handleFault(event:FaultEvent):void {
                            mx.controls.Alert.show(event.message.toString());
                           
                     }
              ]]>
       </mx:Script>

       <mx:DataService id="hibernate" destination="employee.hibernate" fault="handleFault(event)" autoCommit="true" />
       <mx:ArrayCollection id="myArray" />

</mx:Application>

We are now ready to display the list of employees to the user. To do this, we will use the DataGrid control. We then configure the data grid’s data source to be the ArrayList (myArray) and identify which data columns we would like to display in the grid. Just to make things look nice, we will also add some visual controls around the data grid.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="getEmployees()"><mx:Script>
              <![CDATA[
                     import mx.controls.Alert;
                     import mx.rpc.events.FaultEvent;
                     import mx.collections.ArrayCollection;
                     import flash.events.MouseEvent;
                     import mx.rpc.AsyncToken;
                     import mx.data.*;
                     import EmployeeManagement.*;
                              
                     [Bindable]
                     private var employee:Employee;
                    
                     private function getEmployees():void {
                            currentState=”;
                            hibernate.fill(myArray,"all.employees",[]);                     }
                    
                     private function handleFault(event:FaultEvent):void {
                            mx.controls.Alert.show(event.message.toString());
                           
                     }
              ]]>
       </mx:Script>       <mx:DataService id="hibernate" destination="employee.hibernate" fault="handleFault(event)" autoCommit="true" />
       <mx:ArrayCollection id="myArray" />
<mx:VBox width="783" height="562" y="10" x="10">
<mx:ApplicationControlBar width="782" borderColor="#408080" fillColors="[#408080, #408080]" fillAlphas="[0.53, 0.53]" autoLayout="true">
<mx:Text text="Employee Management Console" fontSize="26" fontWeight="bold" fontStyle="italic" themeColor="#ff8000" alpha="0.52"/>
</mx:ApplicationControlBar>
<mx:HBox x="10" y="10" width="783" height="455" id="hbox1">
<mx:Panel  id="listEmployeePanel" width="783" height="455" layout="absolute" title="Employee List" cornerRadius="8" borderColor="#408080" fontSize="13">
       <mx:DataGrid id="dgrid" dataProvider="{myArray}" editable="false" width="763" height="411" bottom="0" right="0">
              <mx:columns>
                     <mx:DataGridColumn headerText="Employee ID" dataField="id"/>
                     <mx:DataGridColumn headerText="First Name" dataField="firstname"/>
                     <mx:DataGridColumn headerText="Last Name" dataField="lastname"/>
              </mx:columns>
       </mx:DataGrid>

</mx:Panel>
</mx:HBox>
       </mx:VBox>

</mx:Application>

 

Save this file as Main.mxml in C:\fds2\jrun4\servers\default\flex\EmployeeManager, launch the Integrated Flex Server (make sure that the database server is running before you do this) and navigate to http://localhost:8700/flex/EmployeeManager/Main.mxml. You should see the Employee Management Console with a list of three employees that we inserted into the database in section 1.2

3.3 Editing employee information: Now that was pretty cool, but what if you would like to change the last name of one of the employees? Would that be difficult? Hardly – this is Flex. One quick way to do this would be to make the data grid control editable.

<mx:DataGrid id="dgrid" dataProvider="{myArray}" editable="true" width="763" height="411" bottom="0" right="0"> 

Now, re-try the application and click on the last name of one of the employees. You are now able to make changes to the database directly. But what if you would like to control the UI and validation of the edit capabilities? Maybe you would like to provide the ability to delete employees from the database. Well that’s simply a matter of Flex design; here is a sample that uses states to manipulate the application interface when a user clicks on an item in the data grid:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="getEmployees()">
<mx:Script>
              <![CDATA[
                     import mx.controls.Alert;
                     import mx.rpc.events.FaultEvent;
                     import mx.collections.ArrayCollection;
                     import flash.events.MouseEvent;
                     import mx.rpc.AsyncToken;
                     import mx.data.*;
                     import EmployeeManagement.*;
                     import mx.managers.PopUpManager;
                     import mx.core.IFlexDisplayObject;
                     private var token:AsyncToken;
                    
                     [Bindable]
                     private var employee:Employee;
                    
                     private function getEmployees():void {
                            currentState=”;
                            hibernate.fill(myArray,"all.employees",[]);

                     }
                    
                     private function deleteEmployee():void {
                            try
                            {
                                  hibernate.deleteItem(dgrid.selectedItem);
                                  hibernate.commit();
                                  getEmployees();
                            }
                            catch(e:Error)
                            {}
                     }
                    
                     private function editHandler():void {
                            currentState=’EditEmployee';
                            empID.text = dgrid.selectedItem.id;
                            fname.text = dgrid.selectedItem.firstname;
                            lname.text = dgrid.selectedItem.lastname;
                     }
                    
                     private function saveChanges():void {
                            // Simply by setting the values in the datagrid, the datasource will detect changes and commit them.
                            dgrid.selectedItem.firstname = fname.text;
                            dgrid.selectedItem.lastname = lname.text;
                            // refresh list and go back to original state
                            getEmployees();
                     }
                    
                     private function cancelChanges():void {
                            getEmployees();
                     }
                    
                    
                     private function handleFault(event:FaultEvent):void {
                            mx.controls.Alert.show(event.message.toString());
                           
                     }
              ]]>
       </mx:Script>
      
       <mx:transitions>
              <mx:Transition fromState="*" toState="*">
                     <mx:Parallel targets="{[listEmployeePanel,dgrid]}">
                            <mx:Resize duration="400"/>
                     </mx:Parallel>
              </mx:Transition>
             
       </mx:transitions>

       <mx:DataService id="hibernate" destination="employee.hibernate" fault="handleFault(event)" autoCommit="true" />
       <mx:ArrayCollection id="myArray" />
       <mx:VBox width="783" height="562" y="10" x="10">
              <mx:ApplicationControlBar width="782" borderColor="#408080" fillColors="[#408080, #408080]" fillAlphas="[0.53, 0.53]" autoLayout="true">
                     <mx:Text text="Employee Management Console" fontSize="26" fontWeight="bold" fontStyle="italic" themeColor="#ff8000" alpha="0.52"/>
              </mx:ApplicationControlBar>
              <mx:HBox x="10" y="10" width="783" height="455" id="hbox1">
                     <mx:Panel  id="listEmployeePanel" width="783" height="455" layout="absolute" title="Employee List" cornerRadius="8" borderColor="#408080" fontSize="13">
                            <mx:DataGrid id="dgrid" dataProvider="{myArray}" editable="false" width="763" height="411" bottom="0" right="0" click="editHandler()">
                                  <mx:columns>
                                         <mx:DataGridColumn headerText="Employee ID" dataField="id"/>
                                         <mx:DataGridColumn headerText="First Name" dataField="firstname"/>
                                         <mx:DataGridColumn headerText="Last Name" dataField="lastname"/>
                                  </mx:columns>
                            </mx:DataGrid>
                     </mx:Panel>
              </mx:HBox>
              <mx:ApplicationControlBar width="783" borderColor="#408080" fillColors="[#408080, #408080]" fillAlphas="[0.55, 0.31]">
                     <mx:Button label="Refresh List" click="getEmployees()"/>
                     <mx:Button label="Delete Selected Employee" click="deleteEmployee()" id="button2"/>
              </mx:ApplicationControlBar>
       </mx:VBox>       <mx:states>
              <mx:State name="EditEmployee">
                     <mx:SetProperty target="{listEmployeePanel}" name="width" value="383"/>
                     <mx:SetProperty target="{dgrid}" name="width" value="363"/>
                     <mx:SetStyle target="{dgrid}" name="right"/>
                     <mx:SetProperty target="{dgrid}" name="x" value="0"/>
                     <mx:SetProperty target="{dgrid}" name="y" value="0"/>
                     <mx:SetStyle target="{dgrid}" name="bottom"/>
                     <mx:AddChild relativeTo="{hbox1}" position="lastChild">
                            <mx:Panel  id="editEmployeePanel" width="389" height="455" layout="absolute" title="Edit Employee" cornerRadius="8" borderColor="#408080" fontSize="13">
                                  <mx:Form id="editform" x="38.5" y="114">
                                         <mx:FormItem label="Employee ID">
                                                <mx:TextInput id="empID" editable="false" backgroundColor="#d7d7d7"/>
                                         </mx:FormItem>
                                         <mx:FormItem label="First Name">
                                                <mx:TextInput id="fname"/>
                                         </mx:FormItem>
                                         <mx:FormItem label="Last Name">
                                                <mx:TextInput id="lname"/>
                                         </mx:FormItem>
                                  </mx:Form>
                                  <mx:Button x="73.5" y="257" label="Save" click="saveChanges()"/>
                                  <mx:Button x="143.5" y="257" label="Delete" click="deleteEmployee()"/>
                                  <mx:Button x="224.5" y="257" label="Cancel" click="cancelChanges()"/>
                            </mx:Panel>
                     </mx:AddChild>
                     <mx:RemoveChild target="{button2}"/>
          

Download files

Comments Closed