[Helma-NG] hibernate integration
Marius.Lessiak at orf.at
Marius.Lessiak at orf.at
Thu Jun 12 12:06:46 CEST 2008
heyo list,
As Philipp pointed out last month i showed some interest in integrating
helma-ng with hibernate for ORM purposes (during the helma-meeting at
werkzeugH). When I finally took some time last week to dig into the
topic I was positively surprised that Robert had already coded a
splendid prototype. Thanks for that - blog-ng_hibernate is perfectly
suitable for toying around. I'll try and explain what my conclusions are
for now:
It seems that hibernate integrates easily into the helma-ng rhino JS
environment. The database session spawned by the hibernate session
factory is correctly attached to the current thread and works just fine.
A minor inconvenience is the necessity to use overloaded java methods
via explicit JS function calls in hibernate.js (see
<http://www.mozilla.org/rhino/ScriptingJava.html>, "Calling overloaded
methods"). Robert encapsulated standard generic DAO (see
<http://www.hibernate.org/328.html>) functionality in the module
hibernate.js which is loaded where necessary via importModule as db.
Besides using db as generic DAO for handling of domain objects (like an
Article for example) there is also some DAO code inside the objects -
e.g. doUpdate() which calls db.save(). I think in principle that's o.k.,
especially for allowing an intuitive coding style where
Article.doUpdate() (maybe rename it to Article.save()) can be used
instead of db.save(Article). But I think it should be avoided to get
hibernate specific code inside of domain objects, instead put it inside
a generic DAO where it is easy maintainable. Discussing that with some
people we felt it would be nice to do it similar as django:
*) have DAO functionaliy inside object constructors: var article =
Article.getById(1)
*) add convenience function calls that access the DAO (e.g. constructor
functions) to domain objects: article.delete()
Domain objects can inherit DAO functionality from a generic object by
wrapping them (adapter design pattern) instead of using prototype
inheritance. Using adapters instead of prototype chains is already in
use with JSAdapter so that should work. Hannes does it that way in the
minibase app using the function Storable().
Besides inheriting functionality the constructors also need to be
provided with a reference to the current hibernate session which can be
done via a decorator function. In minibase that's done by
Store.registerType(ctor): the function decorates the passed constructor
with DAO specific functions. When using hibernate it can also add the
session (bound to the current thread) to the constructor.
Attached is also an archive with some patches for blog-ng_hibernate,
they address a few glitches in handling hibernate:
*) I added configuration options in db.properties to attach the current
db session to the thread, to use connection pooling via c3p0 and to use
second level caching via EhCache.
*) Currently the session obtained from the SessionFactory is never
closed. That means every request uses the same session and objects never
get removed. Eventually this leads to an OutOfMemoryException not
mentioning the possible transaction errors. I replaced this with a call
to SessionFactory.getCurrentSession() which either get's the current
session for the tread or spawns a new one. In main.js I added callbacks
for onRequest and onResponse where a transaction for the current session
is started (onRequest) and commited (onResponse): i.e. the transaction
works on request-scope.
*) I modified the mapping files for Article and User to allow caching in
the second level EhCache. In a productive environment that is absolutely
necessary to reduce load on the db server.
*) hibernate.js now has a list() function using hibernates criteria
extractor object which allows for caching of SQL statements and result
sets by setting setCacheable(true). That (db.list()) is used in blog.js
main_action instead of db.find().
*) ehcache.xml shows a sample configuration for blog-ng_hibernate:
defined is a default cache as well as specific caches for the domain
objects and for custom sql queries.
*) For EhCache and c3p0 to work it is necessary to add ehcache-1.2.3.jar
and c3p0-0.9.1.jar (for example from inside the hibernate package
download <
http://sourceforge.net/project/showfiles.php?group_id=40712&package_id=1
27784&release_id=574498>) .
Yesterday I filed a bug report with helma-ng stating that it would be
nice to be able to set the classpath. That is in general not possible
(as maks also pointed out) when using java -jar . For my development I
rearranged a tiny bit of java code to be able to call
org.helma.tools.launcher.Runner directly and setting the classpath via
java -cp. Ehcache as well as hibernate both search for a configuration
(hibernate.cfg.xml and ehcache.xml) inside the classpath, I think that
is a nice feature we should try to support. Besides I did not find a way
to programmatically pass an instantiated CacheManager object (like maks
pointed out) to hibernate. Supporting the class path way we would also
get rid of programmatically configuring the hibernate configurator with
a hardcoded properties file.
So what's now to be done:
*) Design a clean interface to plug hibernate into, maybe the one I
proposed above using constructors as DAOs and adapters plus decorators.
If possible the goal should be to provide an interface that can also
handle other persistence providers like JPOX or any other JDO
implementation.
*) Discuss if the manual creation of Hibernate mapping configuration
files (e.g. Article.hbm.xml) is suitable. A nicer approach could be to
have some functionality that can parse JS object definitions and create
the mapping files automatically.
*) Devise a way to enable the use of multiple datasources. That can be
done by instantiating and managing multiple hibernate SessionFactory
objects and managing them. Alternatively the use of a JTA like for
example JOTM <http://jotm.objectweb.org/> is thinkable. That would also
have the benefit of transactions that span multiple datasources and can
live outside a request scope (see <http://www.hibernate.org/42.html>).
*) Testing, testing, testing: Performance, data integrity, transaction
safeness etc.
Looking forward to your comments, keep up the good work.
cheers,
marius
-------------- next part --------------
A non-text attachment was scrubbed...
Name: blog-ng_hibernate_patch.zip
Type: application/x-zip-compressed
Size: 4001 bytes
Desc: blog-ng_hibernate_patch.zip
Url : http://helma.org/pipermail/helma-ng/attachments/20080612/d81c4661/attachment.bin
More information about the Helma-NG
mailing list