« Discover the power of an improved user experience | Main | ColdFusion And LiveCycle Forms Sample »

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

I have everything all setup but doesnt work for me. I think there is a problem with mySql version 5 if used with Hibernate.

Do you know of any other samples using Hibernate?

A co-worker of mine had this working my MySQL 5. Can you give me some details on what the problem you are having is?

Thanks.

Thanks for sharing the sample, I was able to get the sample up running.

Hi,

I am trying to get this sample to work properly. I installed the latest mySQL server release, and followed the directions (I think I did, anyway.) However, when loading the flex application, get the following message:

http://img.waffleimages.com/img/07984dffcdf2847ff88e3822bd27a06f9a78a750/error.png

(Sorry, it was a long error message and taking a screencap was the easiest solution.)

Sean,

Would it be possible for you to send me the App Server log file to mboucher@adobe.com?

Obviously a connection failed error. In MySQL 5, you are forced to provide a password for the root account. In the sample files I provide, there is no password defined for root since MySQL 4 does not require it. The database login credentials are set in the hibernate.cfg.xml (step 2.4) above.

Hi, I have tried this example but i failed to get it running, i think i cant get access to the database since nothing shows up when i browse to it. The datagrid stays empty. I noticed something, when i start the flex integrated server, it throws some exceptions as well before it starts. the very first exception is that: Caused by: org.dom4j.DocumentException: Error on line 1 of document : Document root element is miss
ing. Nested exception: Document root element is missing.
at org.dom4j.io.SAXReader.read(SAXReader.java:482)
at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:422)
PLEASE HELP ME. Wesam

Hi,

When i browse the link, a popup shows up saying the following:
Please Help

(mx.messaging.messages::ErrorMessage)#0
body = (Object)#1
correlationid = "some long id"
destination = ""
extendedData = (null)
faultCode = "Client.Error.MessageSend"
faultDetail = "Channel.Connect.Failed error null"
faultString = "Send failed"
headers = (Object)#2
messageId = "some long id"
rootCause = (Object)#3
code = "NetConnection.Connect.Failed"
level = "error"
timestamp = 0
timeToLive = 0

Please Help

wesam,

You problem is most likely related to an error in your hibernate.cfg.xml file. Could you either send me your file - or compare it to what I have in step 2.4. Based on the error when starting up your Flex server, the XML file is at fault.

Hello!
Thanks for great article, helped me to understand how to start with FDS!
I have build small test app based on your article code (difference is only on my Java persistent object and mapping file), datagrid is filled succesfully, but when I tried to edit and save field directly in datagrid, I got Unable to access UserTransaction in DataService error..
In google, such error found only in adobe technote about deploying on tomcat, but I use fds2 express with integrated jrun!
Please help !
Igor

Igor,

Are you certain that you have an ID field implemented by your persistent object?
I recall a similar error when I made a mistake defining the hibernate id field. This field is mandatory to create a hibernate transaction.

Hello!
Thanks for response Marcel..

Have found where my trouble - all was very simple: while creating app, I had copied jta.jar from hibernate 3.1 distro into my app lib folder, but it looks like jrun already has JTA included in its jrun.jar. Deleted my jta.jar and all works fine; am not sure what is the 'real' problem is, looks like conflict between 2 JTA implementations or so, not a guru in this question :)

Thanks!

Hi

Good sample

I used the logic to connect to an oracle 9i database.

This app is excellent to build on

Hi,
Thanks for this example!
Any idea how to add records?
M.

Milan,

Excellent point!
Thanks for the prefect opportunity to complete this sample.
Check out this post

Wow! Thanks again for excelent examples!
M.

"This is because Hibernate requires a field called id so that it can manage the unique identifier for the object."

This is not exactly true. You tell Hibernate what field to use as the unique identifier.
< id name="id" column="employeeid" >
< generator class="native"/ >
< /id >
I know this isn't a hibernate tutorial but I just thought I would point it out for new users.

I'm getting the same error as a previous poster. I've copied your code twice and resaved the file, no luck. I still get this error. Using MySQL 5, and have added my password to the hibernate.cfg file.


(mx.messaging.messages::ErrorMessage)#0
body = (Object)#1
correlationid = "some long id"
destination = ""
extendedData = (null)
faultCode = "Client.Error.MessageSend"
faultDetail = "Channel.Connect.Failed error null"
faultString = "Send failed"
headers = (Object)#2
messageId = "some long id"
rootCause = (Object)#3
code = "NetConnection.Connect.Failed"
level = "error"
timestamp = 0
timeToLive = 0

Hi Marcel,

great example, but please correct your source entry for "Employee.hbm.xml" the document root tag is cutted off. If someone just copy&paste the code the behaviour of Jason and Wesam may occur!

Hi,

I have a problem with this example. I have some experience with Java and MySQL, but it's the first time I use hibernate. I use my own table from the database and there it goes wrong. The error occurs when I start the flex-server. I get a QuerySyntaxException: tomcatusers is not mapped [From tomcatusers]. Can anyone help me please?

Chris,

Thanks for pointing that out. I made the change.

Karl,

Your problem seems to be related to potential typos in steps 2.3.
Double check that all of the columns that you define in the mapping file are also represented in the Java object and the ActionScript object.

Any chance you can post the files? I re-copied section 2.3, but still get the same error.

Same problem here. I would like to try one more time using the source files.

Thanks for sharing !

Mike and Jason,

Done. Let me know guys...

I have changed the hibernate mapping file and now it works! Thanks a lot guys.

Hi Marcel,

I'm having a problem similar to Milan's - his comments seem to have been deleted, but I found them on the Google cache.

Here's the error message:

faultString: "No destination 'employee.hibernate' exists in service flex.data.DataService

I notice that he was getting this on JBoss.

I'm getting it on Tomcat.

Here's an error that appears in the log when I run the App:

[Flex] RTMP-Server failed to start up: java.net.BindException: Address already in use: bind
Exception in thread "RTMP-Server" flex.messaging.endpoints.rtmp.RTMPException: The RTMP server has encountered a fatal exception starting up: Address already in use: bind
at flex.messaging.endpoints.rtmp.BaseNIORTMPServer.run(BaseNIORTMPServer.java:310)
at java.lang.Thread.run(Unknown Source)

Any thoughts?

Douglas

Hi, i was trying to implement this example but when i render the mxml into the explorer i recive the error message (mx.messaging.messages::ErrorMessage=#0 ......
...
faultString="No destination 'emplouee.hibernate' exists in service flex.data.DataService" i configure the data-managment-config.xml exactly as figure in this tutorial. What can i do?

Thanks.

Hi it's very good tutorial, but i have a question but if i put another field email a i don't wont that exists two user with the same email?
can you help me....

OK, answering my own post, its seems to be an error configuring Tomcat. It doesnt start fds. I dont know why.

Douglas,

Well it seems in the fault string you have 'emplouee.hibernate' and not 'employee.hibernate'. Not sure if this is just a typo when you posted the message.
Also, at one point, I had an extra bogus character in one of the XML config files which I have since fixed... Please double check that you did not copy and paste the error in one of your files.

I am having the same issue when saving to the Hibernate Assembler. I receive the "Unable to access UserTransaction in DataService" error. Has anyone else experienced this problem? Any help is appreciated.

thanks
-adam

Hi Boucher,

Thanks for nice article.

I have setup everything but I face the same problem as AR posted:

mx.messaging.messages::ErrorMessage)#0
body = (Object)#1
correlationid = "some long id"
destination = ""
extendedData = (null)
faultCode = "Client.Error.MessageSend"
faultDetail = "Channel.Connect.Failed error null"
faultString = "Send failed"
headers = (Object)#2
messageId = "some long id"
rootCause = (Object)#3
code = "NetConnection.Connect.Failed"
level = "error"
timestamp = 0
timeToLive = 0

Also

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Main/::editHandler()
at Main/__dgrid_click()


Where i give my mysql jar file name??

I am using some other jar file other than you mentioned in the artcile.

mysql-connector-java-3.0.9-stable-bin

Malik,

Are you using Tomcat?

About the JAR file... You do not need to specify the JAR file anywhere. However, you need to make sure that the class name in the hibernate.cfg.xml matched the JDBC driver that you are using. Then you just need to make sure that driver is in the classpath.

Marcel,

I recently went through your tutorial as well and ran into problems using the current Java 1.5 JDK's compiler rather than older Java 1.4.2 JDK (as you're using).

I would get errors similar to some of those posted in the comments when using a .class bytecode file that I compiled using the Java 1.5 compiler, whereas if used your copy or if I compile specifying 1.4 as source and target versions, the .class file would work just fine.

I ended up modifying my JRun 4 installation to point to a the Java 1.5 VM rather than the default 1.4.2 one so I could use my class file instead, though reverting to the 1.4.2 JDK also works.

I suspect that some of your other readers might be running into a similar issue.

Hi Marcel,

I would just like to say what a great tutorial this is. Its a really good start for anyone using flex. I did have a few problems with the JDBC driver but managed to fix it my downloading a new version of mysql-connector-java-3.0.17-ga from the MySQL website and putting it in the lib folder.

I would just like to know if you can offer any examples of using this method with a relational databases.

Hi,

When i browse the link, a popup shows up saying the following:


(mx.messaging.messages::ErrorMessage)#0
body = (Object)#1
correlationid = "some long id"
destination = ""
extendedData = (null)
faultCode = "Client.Error.MessageSend"
faultDetail = "Channel.Connect.Failed error null"
faultString = "Send failed"
headers = (Object)#2
messageId = "some long id"
rootCause = (Object)#3
code = "NetConnection.Connect.Failed"
level = "error"
timestamp = 0
timeToLive = 0

Please Help

Great Examples ... I found very little help on setting up Flex to talk to Oracle. After Looking at your examples I was able to get my site up and running. Please more examples using Flex!!!!!

Thanks Marcel, for your very nice compilation. It was indeed helpful how to connect a Flex app to an Hibernate-based backend.

Although I like the ease by using the Data Management facility, I am a bit sceptical, if a direct link from the UI to the DB is really best practice. It might match to CRUD-centric apps, but for more complex applications you want that the server-side business logic used for data access. What is your recommendation here? In which situations is using the HibernateAssembler advisable?

Cheers,
Niko

I get this errors when I start the Integrated Flex Server:

Unable to create service 'flex.data.DataService' for 'data-service'

[1]flex.messaging.config.ConfigurationException: Error instantiating application scoped instance of type 'flex.data.assemblers.Hibernat
eAssembler' for destination 'employee.hibernate'.

Could not pre-load servlet: MessageBrokerServlet

---------------
if I run your application the error is :

(mx.messaging.messages::ErrorMessage)#0
body = (null)
clientId = (null)
correlationId = "B5C1889C-CEAC-97BD-0DB9-9B6D89C6F84E"
destination = "employee.hibernate"
extendedData = (null)
faultCode = "Server.Processing"
faultDetail = (null)
faultString = "No destination 'employee.hibernate' exists in service flex.data.DataService"
headers = (Object)#1
messageId = "1A766DCF-2508-8347-C1ED-D21DCF1C04E2"
rootCause = (null)
timestamp = 1166543784437
timeToLive = 0
-----
what can I do ? :(
PS: I downloaded the sources.. and changed nothing (after many attempts to do it differently)

Hi,

This sample application works fine if i run it using the downloaded files but when i try to compile the Employy.java class manually thru javac , the file compiles without any error but the size of the class file increases and the program does not run. Please help me!

-Mini

Hi,

I am getting the same error as some other guys:

faultCode = "Client.Error.MessageSend"
faultDetail = "Channel.Connect.Failed error null"

Has anyone figured out how to solve it?

Thanks a lot!
Yevgeniy

good example
post more examples regarding the flex as a front end with struts+hibernate back end

hi,
When i was browsing the link, a popup showed up saying the following:

(mx.messaging.messages::ErrorMessage)#0
body = (Object)#1
correlationid = "some long id"
destination = ""
extendedData = (null)
faultCode = "Client.Error.MessageSend"
faultDetail = "Channel.Connect.Failed error null"
faultString = "Send failed"
headers = (Object)#2
messageId = "some long id"
rootCause = (Object)#3
code = "NetConnection.Connect.Failed"
level = "error"
timestamp = 0
timeToLive = 0

NOW IT WORKS! :)

1st Problem:
Employee.hbm.xml should start like this


"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

2nd Problem:
if I create Employee.class with javac.exe version 1.5.0_06 it doesn't work

if I create Employee.class with javac.exe version 1.2.2 it WORKS

Thnx

Cool and fine work Marcel...
After seeing this example only i am enthusiastic to explore more int to Flex...

Cheers,
Anand.G

Hey!!! cool exercise!!
thank“s a lot, works fine and its a simple but very functionality example...

I would like translate to spanish, what do you think?? Can I???

Great example. Can anyone post the hibernate mapping file for connecting to Oracle Environment.

hi,
i useing the hibernate3 and my sql4,
my program after one day throws this exceptions:

STACKTRACE:

java.io.EOFException
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java(Compiled Code))
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:1539)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1930)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1168)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1279)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2281)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1634)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:120)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1272)
at org.hibernate.loader.Loader.doQuery(Loader.java:391)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:218)
at org.hibernate.loader.Loader.doList(Loader.java:1593)
at org.hibernate.loader.Loader.list(Loader.java:1577)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:111)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1322)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:300)
at bean.Products.getHomePageList(Products.java:190)
at org.apache.jsp.index_jsp._jspService(index_jsp.java:67)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:94)
at javax.servlet.http.HttpServlet.service(HttpServlet.java(Compiled Code))
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:324)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236)
at javax.servlet.http.HttpServlet.service(HttpServlet.java(Compiled Code))
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java(Compiled Code))
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java(Compiled Code))
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java(Compiled Code))
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java(Compiled Code))
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java(Compiled Code))
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java(Compiled Code))
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java(Compiled Code))
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java(Compiled Code))
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java(Compiled Code))
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java(Compiled Code))
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java(Compiled Code))
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java(Compiled Code))
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java(Compiled Code))
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java(Compiled Code))
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java(Compiled Code))
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java(Compiled Code))
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java(Compiled Code))
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java(Compiled Code))
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java(Compiled Code))
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java(Compiled Code))
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:567)


** END NESTED EXCEPTION **

help me,
Thanks a lot!

Hello Mr. Marcel, I have followed the specified steps thoroughly, but when I run the application it prompts with following error:

[MessagingError message='Unknown destination 'employee.hibernate' for service with id 'data-service'.']
at mx.messaging.config::ServerConfig$/getProperties()
at mx.data::Metadata$iinit()
at mx.data::ConcreteDataService$iinit()
at mx.data::ConcreteDataService$/getService()
at mx.data.mxml::DataService/set destination()
at Main/::_DataService1_i()
at Main$iinit()
at mx.managers::SystemManager/create()
at mx.managers::SystemManager/::initializeTopLevelWindow()
at mx.managers::SystemManager/::frameEndHandler()

Please help me out, & it would be great if you also share some hibernate/flex configuration resources(reading material), thanks!

Everyone is done, all the libraries are placed in the exact folder etc, when I run the Main.mxml file I get this error:

(mx.messaging.messages::ErrorMessage)#0
body = (object)#1
correlationId="C87E25 ..."
destination = ""
extendedData = (null)
faultCode = "Client.Error.MessageSend"
faultDetail="Channel.Connect.Failed error null"
faultString = "Send failed"
headers =(Object)#2
messageId = "e5.."
rootCause = (object)#3
code = "NetConnection.Connect.Failed"
level="error"
timestamp = 0
timeToLive=0

** I am using Tomcat 5.5

For all of you using Tomcat and are running into problems with the data connection, please review Christophe's blog post http://coenraets.org/blog/2007/01/flex-test-drive-server-for-java-developers-tomcat-based/.
There are some Tomcat-specific steps you will need to take.

For those getting a connection refused error, or MessagingServlet could not pre-load, you probably have another Flex web app deployed on your app server and you are getting port conflicts. Edit your services-config.xml and change port 2038 to something else.

Hello, I have configured the application on Tomcat, its running fine & fetching the data from the database, but when I manipulate with the data (either Add New Employee, Update Employee or Remove Employee)
I get this error:
(mx.messaging.messages::ErrorMessage)#0
body = (null)
clientId = (null)
correlationId = "A698A1EC-9841-C68A-9B56-9ADB36DB2786"
destination = "employee.hibernate"
extendedData = (null)
faultCode = "Server.Processing"
faultDetail = (null)
faultString = "Unable to access UserTransaction in DataService."
headers = (Object)#1
messageId = "8A1137A0-FA1C-6E29-5FD0-A9FD3CA8D9AC"
rootCause = (Object)#2
cause = (null)
explanation = "Cannot create resource instance"
localizedMessage = "Cannot create resource instance"
message = "Cannot create resource instance"
remainingName = (null)
resolvedName = (null)
resolvedObj = (null)
rootCause = (null)
timestamp = 1170829162906
timeToLive = 0

Please, help!
thanks!

Same problem as reported by Nasir (OS-X, Tomcat 5.5.20, PostgreSQL 8.2.3)

Hi,
I have the same problem to delete, add or update data.
I am running the sample on tomcat 5.5 and there are no log for this error (execpt the one you posted)

Have you found a solution to this issue ?

Thinks for this sample by the way

Pierre

Hi, i got the following error when i run this example.


Could not pre-load servlet: MessageBrokerServlet
[2]org.hibernate.HibernateException: Could not parse configuration: /hibernate.cfg.xml
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1376)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1310)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1296)
at flex.data.assemblers.HibernateAssembler.createHibernateConfiguration(HibernateAssembler.java:159)
at flex.data.assemblers.HibernateAssembler.initialize(HibernateAssembler.java:135)
at flex.messaging.factories.JavaFactory$JavaFactoryInstance.createInstance(JavaFactory.java:254)
at flex.messaging.factories.JavaFactory.createFactoryInstance(JavaFactory.java:93)
at flex.messaging.FactoryDestination.getFactoryInstance(FactoryDestination.java:76)
at flex.data.adapters.JavaAdapter.server(JavaAdapter.java:158)
at flex.data.adapters.JavaAdapter.setSettings(JavaAdapter.java:119)
at flex.messaging.Destination.createAdapter(Destination.java:279)
at flex.messaging.Destination.initDestination(Destination.java:103)
at flex.messaging.FactoryDestination.initDestination(FactoryDestination.java:58)
at flex.data.DataService.createDestination(DataService.java:90)
at flex.messaging.services.AbstractService.createDestinations(AbstractService.java:82)
at flex.messaging.config.MessagingConfiguration.createServices(MessagingConfiguration.java:187)
at flex.messaging.config.MessagingConfiguration.configureBroker(MessagingConfiguration.java:84)
at flex.messaging.MessageBrokerServlet.init(MessageBrokerServlet.java:105)
at jrun.servlet.WebApplicationService.loadServlet(WebApplicationService.java:1200)
at jrun.servlet.WebApplicationService.preloadServlets(WebApplicationService.java:791)
at jrun.servlet.WebApplicationService.postStart(WebApplicationService.java:293)
at jrun.deployment.DeployerService.initModules(DeployerService.java:711)
at jrun.deployment.DeployerService.createWatchedDeployment(DeployerService.java:242)
at jrun.deployment.DeployerService.deploy(DeployerService.java:430)
at jrun.deployment.DeployerService.checkWatchedDirectories(DeployerService.java:179)
at jrun.deployment.DeployerService.run(DeployerService.java:891)
at jrunx.scheduler.SchedulerService.invokeRunnable(SchedulerService.java:230)
at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
Caused by: org.dom4j.DocumentException: Error on line 3 of document : XML declaration may only begin entities. Nested exception: XML declaration may only begin entities.
at org.dom4j.io.SAXReader.read(SAXReader.java:482)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1366)
... 28 more
[1]flex.messaging.config.ConfigurationException: Error instantiating application scoped instance of type 'flex.data.assemblers.HibernateAssembler' for destination 'employee.hibernate'.
at flex.messaging.factories.JavaFactory.createFactoryInstance(JavaFactory.java:117)
at flex.messaging.FactoryDestination.getFactoryInstance(FactoryDestination.java:76)
at flex.data.adapters.JavaAdapter.server(JavaAdapter.java:158)
at flex.data.adapters.JavaAdapter.setSettings(JavaAdapter.java:119)
at flex.messaging.Destination.createAdapter(Destination.java:279)
at flex.messaging.Destination.initDestination(Destination.java:103)
at flex.messaging.FactoryDestination.initDestination(FactoryDestination.java:58)
at flex.data.DataService.createDestination(DataService.java:90)
at flex.messaging.services.AbstractService.createDestinations(AbstractService.java:82)
at flex.messaging.config.MessagingConfiguration.crea