“Zero Code” Data Access using LiveCycle Data Services Runtime Configuration

When using the LCDS data management service, developers usually create a custom assembler for each destination, or use the Hibernate assembler if they happen to use Hibernate as their persistence framework. Other developers don’t use the data management service at all because of its perceived complexity.

The Data Management Service provides a set of low level APIs on top of which you can build your own higher level / higher productivity framework. The Hibernate assembler provides an example of a “generic assembler”, but you can also create your own. When used in this fashion, the Data Management Service can provide, by far, the most productive way to build data-driven applications.

To illustrate this point, I have been showing a demo at a few conferences this year, and I finally decided to package it. The demo combines a generic assembler and the runtime configuration feature of LCDS to provide a zero (server-side) code, zero configuration strategy to build data-driven applications. The demo goes like this:

  1. Create a table in MySQL Query Browser… just to show that I was starting from scratch.
  2. Add a few rows in the new table (still in MySQL Query Browser)
  3. Create a new project in Flex Builder, and with the help of a DynamicDataService class, build a data maintenance application in literally three lines of code.

The key point of the demo was that I didn’t have to write any server-side code, or even configure anything (no XML) at the server-side… a table was all I needed.

Here is a quick and rough version of the demo:

Follow the instruction below to try it on your system:

  1. Download flex-dynamic-data.zip and unzip it on your local file system.
  2. Copy bin/flex-dynamic-data.jar in /tomcat/webapps/lcds-samples/WEB-INF/lib.

    flex-dynamic-data.jar includes two classes: DestinationService and DynamicJDBCAssembler. DestinationService creates data management destinations on the fly. Each destination created by DestinationService uses an instance of DynamicJDBCAssembler to dynamically generate the appropriate SQL statements for the fill, getItem, createItem, updateItem and deleteItem operations. You never have to directly work with or configure these two classes: they are automatically invoked by the client-side DynamicDataService component. The source code is available in /flex-dynamic-data/src/java.

  3. Open remoting-config.xml in lcds-samples\WEB-INF\flex and add the following destination:

        <destination id="destination-factory">
            <properties>
                <source>flex.dynamic.data.DestinationService</source>
            </properties>
        </destination>
    
  4. Copy flex-dynamic-data.properties in /tomcat/webapps/lcds-samples/WEB-INF/classes.

    Open the file. Notice that the default database is set to the HSQLDB sample database (flexdemodb) shipping with the product.

  5. Create a new Flex Builder project. Specify J2EE as the application server type, check the “Use remote object access service” checkbox, uncheck the “Create a combined Java/Flex project using WTP” checkbox, and point to the lcds-samples web application:

    • Root folder: c:\lcds26\tomcat\webapps\lcds-samples
    • Root URL: http://localhost:8400/lcds-samples
    • Context root: /lcds-samples
  6. Add flex_dynamic_data.swc to your build path.

    flex_dynamic_data.swc includes the DynamicDataService class. The source code is available in /flex-dynamic-data/src/as.

  7. Code the application as follows.
    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:data="flex.dynamic.data.*">
    
    	<mx:ArrayCollection id="items"/>
    
    	<data:DynamicDataService id="ds" destination="dynamic.company"
    		ready="ds.fill(items)" />
    
    	<mx:DataGrid dataProvider="{items}" width="100%" height="100%" editable="true"/>
    
    </mx:Application>
  8. Run the application.
  9. Modify data (not the primary key)
  10. Click the refresh button and notice that the data has been persisted.
  11. Open a second browser and access the same URL. Modify data in one browser and notice that changes are automatically being pushed to the other browser.

Disclaimer: The mini framework provided with this sample is for demo purpose only. The goal is not to provide a production quality solution: I took many shortcuts and although it may be good for rapid prototyping, the specific strategy implemented here has serious limitations (single table, no support for associations, etc.). The goal is to illustrate what’s possible when building generic assemblers and runtime configuration, and hopefully generate a few ideas.

Comments

25 Responses to ““Zero Code” Data Access using LiveCycle Data Services Runtime Configuration”

  1. kutu182 on September 12th, 2008 3:36 pm

    7. Run the application.
    “No destination with id ‘destination-factory’ is registered with any service.”

  2. christophe on September 12th, 2008 3:41 pm

    Oops. Good catch: thanks. You need to add the destination-factory declaration in lcds-samples\WEB-INF\flex. I updated the instructions in the post.

  3. kutu182 on September 13th, 2008 2:03 am

    Run the application.

    Tomcat write:
    *** Starting destination dynamic.company
    *** Initializing assembler….
    jdbcDriver: org.hsqldb.jdbcDriver
    jdbcURL: jdbc:hsqldb:hsql://localhost:9002/flexdemodb
    table: company
    identity: [ID]
    autoincrement: true

    in the application nothing (empty)

    sorry for my english.

  4. David on September 13th, 2008 10:14 pm

    Christophe:
    Will this run under BlazeDS or only LCDS?

  5. christophe on September 14th, 2008 7:38 am

    David,
    LCDS only since it leverages the Data Management
    Service.

  6. Phiphou on September 14th, 2008 10:59 am

    Hi Christophe,

    I tried your sample this morning, and did not succeed in making it work.

    I followed your instructions, and receive no errors on server side. Here is what the server console “says” :

    *** Starting destination dynamic.users
    *** Initializing assembler….
    jdbcDriver: com.mysql.jdbc.Driver
    jdbcURL: jdbc:mysql://localhost/taskmanager?zeroDateTimeBehaviour=convertToNull&
    noDatetimeStringSync=true
    table: users
    identity: [ID]
    autoincrement: true
    **** executing fill….
    **** executing statement: SELECT * FROM users
    {user_name=phiphou, user_pswd=, id=1}
    {user_name=David, user_pswd=, id=2}
    {user_name=Renaud, user_pswd=, id=3}
    {user_name=Benoεt, user_pswd=, id=4}

    As you can see, I’m using a MySQL database, but the problem I’m gonna describe below is the same with the hsqldb.

    Flex debugger says :

    “[RPC Fault faultString="No identifier found." faultCode="Client.Processing.NoIdentifier" faultDetail="No Identifier was found when processing a fill or page response."]…”

    And naturally, the datagrid doesn’t show any datas…

    But what is strange to me is that in the variable window of flexbuilder, in Event>message>inherited>body I see my four records.

    Can you help me ?

    Regards

  7. christophe on September 14th, 2008 12:50 pm

    Phiphou,
    Based on the message you get (”No Identifier was found when processing a fill or page response”), the problem seems to be that the Data Service is not able to identify the identity column (primary key) of your data set. By default, the dynamic assembler is going to look for a column called ID (case sensitive). If you want to use another column name, you have to specify that name in the DynamicDataService tag. For example, <data:DynamicDataService identifier=”id” dataProvider=”{items}”/>. Remember that the identity column is case sensitive.

  8. Phiphou on September 14th, 2008 1:56 pm

    Thanks Christophe for your quick and accurate answer.

    You were right, it was caused by the case of my id field, witch was “id” instead of “ID”.

    So I first tried, as you said, to add the identity property (identifier property couldn’t be resolved, you probably made a mistake) to the DynamicDataService tag. But it didn’t fix the problem.

    More, whatever is the name I choose for the identity property, the server console alway says “identity: [ID]” .

    So, I tried to modify the name directly in the database structure, and now, it works fine. So it seems that the identity property is never updated.

    I took a quick look on the Java and Flex source code, and I think I’m able to deal with it (not sure it can be said like that, sorry, I’m a poor french…!)

    So, I thank you again for your answer, but I probably will continue to use LCDS with “the old way”, witch give me more control on what I do… (again, not sure you’ll understand my bad english, sorry :) )

    Bye and “bravo” for all your impressive work.

  9. kutu182 on September 14th, 2008 2:37 pm

    please correct your post

  10. kutu182 on September 14th, 2008 2:39 pm

    sorry

    data:DynamicDataService id=”ds” identity=”COMPANY_ID” destination=”dynamic.company” ready=”ds.fill(items)”

  11. Flex Monkey Patches » Blog Archive » Rubbernecker’s Review - Week 12 on September 16th, 2008 9:43 am

    [...] “Zero Code” Data Access using LiveCycle Data Services… (from Christophe Coenraets) [...]

  12. Ömür D. Dalan on September 17th, 2008 4:51 pm

    I can not get the idea that, why this won’t work on BlazeDS, could you please explain in a few sentences.

  13. Bailey on September 18th, 2008 11:23 am

    Thank you for showing this Christophe :)

    Omur, BlazeDS is a open source subset of LiveCycleDS. One of the things BlazeDS does not have is the “Data Management” service layer which is provided in LiveCycleDS.
    Remember, one is free and one is a paid product. Both can be great.

  14. Albert on September 23rd, 2008 10:34 am

    Hi Christophe,

    Maybe this is not the right place to ask but I’m a big fan of your presentations and I would like to know what kind of software do you use to just type a few letters in Eclipse and then a bunch of text is added? :)

    Please, answer me privately and then delete this post if you want.

    Thank you.

    Albert

  15. David B. on September 23rd, 2008 3:00 pm

    downloaded and ran the testdrive samples in my jboss 4.0.5 runtime. 6 out of the 7 samples run OK. The one that I’m having a problem with is the Sample 2: Accessing data using Web Services. I’m getting an error on it finding the wsdl file: [RPC Fault faultString="HTTP request error" faultCode="Server.Error.Request" faultDetail="Unable to load WSDL. If currently online, please verify the URI and/or format of the WSDL (http://coenraets.org/services/ProductWS?wsdl)"].
    Is there a different location for the wsdl file I could use to get this to work?

  16. Luciano on September 28th, 2008 10:15 pm

    Hi Christophe,

    After compiling, the folowing error appears inside the datagrid:

    [MessagingError message='Destination 'destination-factory' either does not exist or the destination has no channels defined (and the application does not define any default channels.)']

    Do you know who could be the problem?
    Thanks

  17. vlad2005 on September 30th, 2008 1:02 am

    I try to run this simple, but i get an error

    java.lang.NoSuchMethodError : flex.messaging.MessageBroker.getService(Ljava/lang/String;)Lflex/messaging/services/Service;

    flex-dynamic-data.jar is in /webapps/ROOT/WEB-INF/lib, and destination-factory is set in remoting-config.xml.

    all testing samples, work just fine.

  18. spunky on October 4th, 2008 2:59 pm

    I am trying to get this sample running with SQL Server, not MySQL.

    I have modified the properties file as required, but when I run the Flex code I received a “Send Failed” message.

    When this failed, I tried using your default HSQL configuration (using the included flexdemodb database) and I receive the same message.

    What am I missing here? Thanks!

  19. Laurent Bouquet on October 9th, 2008 3:56 am

    Thank you, Mr Coenraets, for your very good tutorial ! ! !

    Now, how many costs LCDS ?
    That’s the question.

  20. vlad2005 on October 10th, 2008 2:02 pm

    Hi!
    I try to implement DynamicDataService, but i request this errror in lcds console:

    [Flex] [ERROR] Exception when invoking service: remoting-service
    with message: Flex Message (flex.messaging.messages.RemotingMessage)
    operation = createDestination
    clientId = 929BA063-FF0D-ADA5-D4D6-344C3C42A6A4
    destination = destination-factory
    messageId = 280A145F-DE36-50BB-E4BE-E815238BC97E
    timestamp = 1223664412015
    timeToLive = 1223664412015
    body = null
    hdr(DSEndpoint) = my-amf
    hdr(DSId) = 929B9FCC-A10C-5501-8D4E-30211E3AB0AC
    exception: flex.messaging.MessageException: java.lang.NullPointerException : n
    ull

    [Flex] [ERROR] Root cause: java.lang.NullPointerException
    at flex.dynamic.data.DestinationService.createDestination(DestinationSer
    vice.java:18)

    At line 18, into DestinationService.class, i have that:
    if (service.getDestination(destinationId) != null)

    I have lcds 2.5.1. and is run with jrun 4.
    What is wrong?

  21. vlad2005 on October 10th, 2008 2:26 pm

    I found how resolve, few minute later. Instead using flex-messaging.jar from lcds, i used from fds-tomcat.

  22. compare insurance companies online on October 19th, 2008 3:25 pm

    compare insurance companies online…

    exiting:emerging worldwide downloads distractions …

  23. Billigflüge on October 28th, 2008 8:22 am

    Thanks for this awesome one, it works nice, especially considering vlads observations. fds-tomcat seems to be the easiest way indeed. Great work!

  24. Dan Zeitman on November 2nd, 2008 2:21 pm

    Hey, getting this error, any thoughts?

    flex.messaging.config.ConfigurationException : Error instantiating application scoped instance of type ‘flex.dynamic.data.DynamicJDBCAssembler’ for destination ‘dynamic.contacts’.

    Also some typo’s:

    should be dynamic.contacts — your video shows a “contacts” table.

    also- you don’t tell us where to create the mysql table “contacts” — should be in a db called “demo”

    What else might be missing that would cause the errors? Also might be helpful to explain the .properties file.

    Zero config seems a bit mis-leading — how about minimal config?

  25. Billigflug on November 19th, 2008 9:09 am

    I have tried to run ur sample, followed the instruction but i have had this error as output:
    java.lang.NoSuchMethodError : flex.messaging.MessageBroker.getService(Ljava/lang/String;)Lflex/messaging/services/Service;

Leave a Reply