Wednesday, May 16, 2007

Javascript and Hibernate, hand in hand

Some time ago I had written a little prototype that was quite interesting, but I never pursued it. Maybe I should try to get some people interested and develop it further...
The idea was to use Rhino to have a Javascript-based framework on the server, thus using the same language on the server and on the client, like ASP did in the good old days. I was also thinking of having the source code for custom applications stored in the database, instead of having it in source files, but that's another story. That explains why the examples below are about "applications" and "components"
The first component is Hibernate connectivity. My framework lets you:
1. Dynamically configure Hibernate mapping for Javascript defined classes. For example, if you wanted to define a Web Application with several attributes and a reference to the components that it defines:

function Application(){
this.displayName='';
this.urlName='';
this.defaultUrl='';
this.id=-1;
this.components=[];
}


Application.storage(
{
id:
{name:'id',column:'ID',type:'long'},
properties:
[
{name:'displayName','not-null':true},
{name:'urlName','not-null':true,unique:true,'unique-key':'APPLICATION_URL'},
{name:'defaultUrl'}
],
references:
[
{'list':
{name:'components',table:'APPLICATION_COMPONENT',
details:[
{'key':{column:'APPLICATIONID'}},
{'list-index':{column:'idx',base:'0'}},
{'many-to-many':{'column':'COMPONENTID','class':'Component'}}
]
}
}
]
}
);

Note that storage() is a function of the Function object which takes a Javascript structure that mimicks the Hibernate XML.

2. Access Hibernate functionality through a "hibernate" host object. For example, a JSUnit method testing the addition of a new "Application" object:

var appId;
var appUrlName;

function testAdd(){
assertNotUndefined(hibernate);
var app=new Application();
assertNotUndefined(app);
app.displayName="TestAppJS"+new Date();
app.urlName=app.displayName;
appUrlName=app.urlName;
hibernate.save(app);
hibernate.commit();
assertNotNaN(app.id);
assertTrue(app.id>0);
appId=app.id;
}

The hibernate object lets you list objects, get a particular object, modify or create instances, etc. I have implemented a Hibernate EntityTuplizer and an subclass of Rhino's NativeArray that encapsulate a PersistentList, so that multiples references can be seen as Javascript arrays.

3. Query the database either through the HQL language:

var apps=hibernate.query("from Application where urlName=?",["TestAppJS"]);

or through a pure Javascript function based mechanism:

var apps=hibernate.query("Application",function(app){
return app.urlName=="TestAppJS";}
);

That I think is very cool. In Rhino I can access the source code of the function that is passed as the second argument to query, and transform it into HQL. I haven't implemented as much as I could, of course, but it works with simple queries. At least there is no other syntax to learn to do a query, it's basically the equivalent of a filter function in functional language.

Then I had started to develop a web framework (probably the millioneth Java web framework by now) with Javascript objects to generate HTML and a mapping between urls and javascript functions, and where one URL could chain several functions, but I haven't gone very far.

Now if somebody feels there's some value in any of that I can sure post the code and we can move it forward. Anything that can show that Javascript is a cool language to run in a JVM in a worthwhile enterprise (-:

5 comments:

Anonymous said...

I would be interested in the:
"source code of the function that is passed as the second argument to query, and transform it into HQL"

Can you post the code pleaz? :-)

JP Moresmau said...

You can find the code at http://www.moresmau.fr/jp/java/src/fr/moresmau/jp/swide/script
There is no javadoc but you can figure out the code. You can obtain a NativeFunction by casting from the proper scriptable object.

Anonymous said...

It's only now that I saw your comment.
I would be interesting in seeing the code.
Thanks,
Dan

Unknown said...

The link is not working. Is the code still available?

JP Moresmau said...

Rob, email me at jp at moresmau dot fr. I have an old zip with the source I could send you.