Annotating ActionScript Classes with Custom Metadata + Simple ORM Framework for AIR

A little known feature of Flex 3 is that you can annotate ActionScript classes with your own metadata. For example you could annotate a class as follows:

package
{
	[Bindable]
	[Table(name="contact")]
	public class Contact
	{
		[Id]
		[Column(name="contact_id")]
		public var contactId:int;

		[Column(name="first_name")]
		public var firstName:String;

		[Column(name="last_name")]
		public var lastName:String;
		public var address:String;
		public var city:String;
		public var state:String;
		public var zip:String;
		public var phone:String;
		public var email:String;
	}
}

In this example, [Bindable] is a standard Flex metadata annotation while Table, Id and Column are custom. The -keep-as3-metadata compiler flag allows you to instruct the compiler to keep your metadata in the generated SWF so that you can get to this information at runtime using the reflection API (describeType).

To set the compiler flag, right-click the AIR project name in FlexBuilder, select “Properties”, and “Flex Compiler”. For this example, I added -keep-as3-metadata+=Table,Id,Column to the “Additional compiler arguments”. Notice that it is important to use += and not =, otherwise standard metadata annotations (like [Bindable]) will not be available in the SWF.

Custom metadata annotations can be used for all sorts of interesting things . For my session at MAX this year, I used custom annotations to build a simple persistence framework for AIR.

Using this framework, you annotate your model classes to indicate the database table that should be used to persist instances of that class, the identity field in your class (which corresponds to the primary key of that table), and name mappings when the database column name is different from the class field name. That’s all you have to do to provide your AIR applications with automatic persistence to the embedded SQLite database. No SQL to write! The framework will even generate the table if it doesn’t already exists.

For example to add a new contact to your database, you’d simply do something like this:

var contact:Contact = new Contact();
contact.firstName = "Christophe";
contact.lastName = "Coenraets";
contact.email = "ccoenrae@adob.com";
entityManager.save(contact);

to modify the contact:

contact.firstName = “Chris”;
entityManager.save(contact);

to remove the contact:

entityManager.remove(contact);

You can provide the entityManager with instances of any annotated class and it will figure out how to persist the object (how to generate the appropriate SQL statements) based on your metadata annotations.

Disclaimer: This is a simplistic proof of concept and is by no means a production ready ORM solution. Some basic assumptions are made for simplicity. For example, I assume that all primary key are autoincremented integers.

You can download the sample application here. To test it, create an AIR project in FlexBuilder, copy the sample files in that project, and set the compiler options as described above.

  • shaun

    Nice. Thanks for the example code.
    After playing with AIR and the embedded SQL functionality I thought I’d have a go a writing a ORM for AIR. This(metadata information) is the missing piece of the puzzle for me. I was considering an alternative approach but i prefer this option.

  • Adding the metadata references as compiler arguments could end up being quite a dirty process if you have a lot of metadata you want to keep and you only have that single line text input comtrol.

    Is there any plan for an option to keep all as opposed to listing them individually?

    keep-as3-metadata=ALL

  • Gregory Pierce

    Are you going to implement the rest of JPA (object graphs and such) or are you leaving this as an exercise for the reader? :)

  • mloncaric

    omg. Thank you very much

  • Pat Ryan

    I attended your session at Adobe Max in Chicago. It was one of the best sessions of the conference.
    When I returned home I started to create a simple application to show the synchronous API, asynchronous API and finally your EntityManager. I created the database outside of the EntityManager so it existed before running the EntityManager create sql.

    I noticed by running it this way the EntityManager did not populate data. It turned out to be an assumption in the typeObject method. In there you had:
    instance[item.field] = o[item.column];
    which assumed the column was upper cased which mine were not. But they would have been if I let the EntityManager create the table. The columns were the same case as the Object property that I was loading so the SQLStatement would populate the object from column name.

    I added the following and was able to get my sample application to work for synch DB, asyncDB as well as your EntityManager.

    instance[item.field] = o[item.field];
    if( instance[item.field] == null ) {
    instance[item.field] = o[item.column];
    }

    Conversely if I created the table with the EntityManager but if I used my syncAPI example it would not work because of the upperCased columns. So I also had to modify the loadMetadata method to not upperCase the column names.

    If you would like to see a test case I can send you my simple example.

    Do you have any thoughts or comments on these changes? If I have misunderstood its usage just let me know.

    Thanks again for a great session and a nice piece of work.

  • Hi Christophe,
    I attended the very last session that you presented at max this year. I liked your session very much it was actually my favorite this year. When i started using air to make something simple to begin with of course a contact manager was the most obvious choice. So when i ran into some bump i used your application as reference. But i am a problem with the relation in this line of code:
    “var identity:Object = map.identity;”
    now when i used it in my code it failed giving a null object yet the object passed to the function arguments was in fact as expected is there anyone who can explain this line within this function?

    private function createItem(o:Object, c:Class):void
    {
    var stmt:SQLStatement = map.insertStmt;
    var identity:Object = map.identity;
    var fields:ArrayCollection = map.fields;
    for (var i:int = 0; i<fields.length; i )
    {
    var field:String = fields.getItemAt(i).field;
    if (field != identity.field)
    {
    stmt.parameters[“:” field] = o[field];
    }
    }
    stmt.execute();
    o[identity.field] = stmt.getResult().lastInsertRowID;
    }

    Thanks

  • Pat Ryan

    Will you be making your presentation from Adobe Max available for download.

    Thanks

  • Pat Ryan

    Hi NetCFmx
    If you make your code available I would take a look as I have time.

    Maybe you could try the new Adobe share beta. It has been a really easy way for me to share files.

    http://www.adobe.com/go/share

  • Hi Pat,

    Thanks for taking the time to look at this i have opened an account so you can get the files they are based on the example that Christophe has posted in his contact manager. Of course i modified a few things to make sure i was able to understand the structure of the code. I am trying to leverage the usage of SQL lite and the relation with the annotation of objects. When i studied the function i could not understand what was going on in the line of code :
    “var identity:Object = map.identity;”

    I miss the relation between the “map” and the property “.identity”.

    Anyways here is the link check it out when you can

    you can message me at wws*at*worldwidesmith*dot*com

    Thank you
    https://share.adobe.com/adc/document.do?docid=68809bd9-785e-11dc-b75f-151d3f6d9313

  • Figures of course two files two links here is the missing link.

    https://share.adobe.com/adc/document.do?docid=6977581e-785e-11dc-b75f-151d3f6d9313

  • Pingback: Sönke Rohde » MAX Barcelona - Short Notes()

  • Great Job. I think I will use this technique as part of my flex proejct.

  • Dan Zeitman

    Great concept. FYI… Since the AIR BETA is a relentlessly moving target… I noted some changes in the AIR API that will need to be addressed in order for your sample to work.

    new SQLConnection(); now takes no args

    in EntityManager.as
    you will need to change line 242:

    _sqlConnection = new SQLConnection(TRUE);

    to

    _sqlConnection = new SQLConnection();

    and in the main.mxml file line 21
    change:

    _sqlConnection = new SQLConnection(TRUE);

    to

    _sqlConnection = new SQLConnection();

  • I have just started building my first AIR application and I was terrified that I have to go back to SQL again. After I had spent for almost two years with Rails and ActiveRecord I almost forgot that SQL exists :-)

    But actually I think that it will not take much long for some ORM project to appear.

  • ICQManZ

    Prodaiy ICQ za 12$ za vse.Ïðîäàþ ICQ 12$ çà âñå.
    274-693
    324-994
    564-567
    605-800
    695-769
    985-425
    132-335
    478-575
    Sviaz so mnoi ICQ 458411483. Ñâÿçü ñî ìíîé ICQ 458411483

  • Ricerca Farmacie. Inserisci il tuo CAP o la localita che ti interessa. CAP o localita. Se vuoi restringere la ricerca inserisci anche l’indirizzo comprare viagra on line

  • Pingback: Salesbuilder Beta 3 (AIR file + Flex Source Code) : Christophe Coenraets()

  • Pingback: » air orm()

  • Pingback: Anonymous()

  • — UPDATE —

    Again what a great technique… I’m using it to map value objects from one to another…

    FYI — Final release of Flexbuilder 3.0 doesn’t support the option=value syntax!!!!

    Instead you must repeat the option = value:

    -keep-as3-metadata “Column”
    -keep-as3-metadata “ID”
    -keep-as3-metadata “Table”

  • Thanks for that I had no idea you could add your own Metadata tags to your actionscript files.

  • Pingback: online amerikansk roulette()

  • Pingback: Sönke Rohde » Open Source and Flex()

  • I will be using your Simple ORM as an example of projects that use metadata in my 360 Flex presentation this next week. I hope you don’t mind.

    I am presenting on how to use metadata and Proxy to create better APIs and will site you as someone who has done this.

    [Tink]: With Flex Builder 3, if your SWC was compiled with the -keep-as3-metadata option, any project the SWC is used in don’t need to add it. It will be added automatically! Helps since the -keep-as3-metadata=ALL isn’t available.

  • omg. Thank you very much

  • Thank you very much

  • thanks thanks thanks :)

  • cryptos

    Thanks Google that helps me to find this site!

  • cryptos

    Thank you very much! I’ll use this technique as part of my new proejct.Try to see this blog – Sexy Latina Maids

  • Is there any plan for an option to keep all as opposed to listing them individually?

    keep-as3-metadata=ALL

  • Thanks Google that helps me to find this site!

  • Pingback: FrameworkQuest 2008 Part 4: IoC With Swiz « aodz()

  • Pingback: Christophe Coenraets » Blog Archive » Using the SQLite Database Access API in AIR… Part 3: Annotation-Based ORM Framework()

  • Thanks for that I had no idea you could add your own Metadata tags to your actionscript files.

  • Has anyone tryed to map data on multiple related tables? Would be a really nice feature to be able to take orm at this level of abstractization. Tx for this class, it’s awesome ^_^

  • Again what a great technique… I’m using it to map value objects from one to another…

    FYI — Final release of Flexbuilder 3.0 doesn’t support the option=value syntax!!!!

    Instead you must repeat the option = value:

    -keep-as3-metadata “Column”
    -keep-as3-metadata “ID”
    -keep-as3-metadata “Table”

  • Хорошо написано, приятно полистать ваш сайт!

  • how are you baby melisa

  • thanks sites

  • Thanks for that I had no idea you could add your own Metadata tags to your actionscript files.

  • good post admin..

  • Thanks for that I had no idea you could add your own Metadata tags to your actionscript files.

  • thanks I think I will use this technique as part

  • Thanks for that I had no idea you could add your own Metadata tags to your actionscript files.

  • After I had spent for almost two years with Rails and ActiveRecord I almost forgot that SQL exists

  • Good information and good way your blog post. Good luck blogger man.

  • Thanks for that I had no idea you could add your own Metadata tags to your actionscript files.

    مدونة الاماكن

  • Well done and good luck with your very great work thanks

  • Metadata tags to your actionscript files.

  • Good luck blogger man.

  • thanks for information

  • This is really useful. I can imagine people not understanding its function correctly though.

  • Thanks for that I had no idea you could add your own Metadata tags to your actionscript files.

  • Spend all day trying to figure out why my compiled AIR app was not outputting the Meta data when using describeType() – just stumbled across your site + the “-keep-as3-metadata+=Table,Id,Column” compiler argument! You’ve saved the day – thanks!

    R

  • Very nice sharing.thanks.

  • why my compiled AIR app was not outputting the Meta data when using describeType() – just stumbled across your site + the “-keep-as3-metadata+=Table,Id,Column” compiler argument! You’ve saved the day – thanks!

  • Best of the best blog Tenks admin you power blog

  • nice ! admin

  • xbha kdcln free sex videos cxycvd d jh n wkj

    jfka sdaiu [URL=http://www.frannysex.com]adult movies[/URL] thodhj u fz l oan

  • Pingback: Digging into Custom Metadata Tag in Flex and ActionScript « ravigeek()

  • thank you admin .!

  • Thanks for this very useful post. I spent several hours (!) trying to figure out why info in Inspectable tags of getters/setters appeared in the XML returned by flash.utils.describeType() in a Debug build, but not in a Release build. After much Googling, I found your post and the tip to use -keep-as3-metadata in the compiler options. I added this
    -keep-as3-metadata+=Inspectable
    to my compiler settings, and voilà – problem fixed. Thanks!

  • We are a gaggle of volunteers and opening a new scheme in our
    community. Your web site offered us with useful information to work on.

    You’ve done an impressive task and our entire community can be grateful to you.

  • I like it whenever people come together and share views. Great site, keep it up!

  • thnx admin sites

  • obrg amigo

  • keşif bir harika,kalite burda.http://www.jonsunsport.com/spor-coraplari.html

css.php