“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:
- Create a table in MySQL Query Browser… just to show that I was starting from scratch.
- Add a few rows in the new table (still in MySQL Query Browser)
- 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:
- Download flex-dynamic-data.zip and unzip it on your local file system.
-
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.
-
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> -
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.
-
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
-
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.
- 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> - Run the application.
- Modify data (not the primary key)
- Click the refresh button and notice that the data has been persisted.
- 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”
Leave a Reply









7. Run the application.
“No destination with id ‘destination-factory’ is registered with any service.”
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.
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.
Christophe:
Will this run under BlazeDS or only LCDS?
David,
LCDS only since it leverages the Data Management
Service.
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
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.
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.
please correct your post
sorry
data:DynamicDataService id=”ds” identity=”COMPANY_ID” destination=”dynamic.company” ready=”ds.fill(items)”
[...] “Zero Code” Data Access using LiveCycle Data Services… (from Christophe Coenraets) [...]
I can not get the idea that, why this won’t work on BlazeDS, could you please explain in a few sentences.
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.
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
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?
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
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.
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!
Thank you, Mr Coenraets, for your very good tutorial ! ! !
Now, how many costs LCDS ?
That’s the question.
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?
I found how resolve, few minute later. Instead using flex-messaging.jar from lcds, i used from fds-tomcat.
compare insurance companies online…
exiting:emerging worldwide downloads distractions …
Thanks for this awesome one, it works nice, especially considering vlads observations. fds-tomcat seems to be the easiest way indeed. Great work!
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?
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;