Friday, July 27, 2007

ActiveHibernate: time to package

Good news. Hibernate collection mapping is up and running. Well, one example that is: Hibernate's bag type now works with Ruby Array's, lazy loading included. To get started I've done a shameless copy/paste of the Hibernate code for the bag collection type. That went fairly easy because the Java class RubyArray implements the java.util.List interface. So now the mapping files look like



<hibernate-mapping>

<class table="BLOGS" lazy="false" entity-name="Blog">

<tuplizer entity-mode="dynamic-map"
class="activehibernate.RubyTuplizer"/>

<id name="id" column="BLOG_ID" type="long">
<generator class="identity"/>
</id>

<property name="title" type="string" />

<bag name="items"
collection-type="activehibernate.RubyArrayType">
<key column="blog_id" />
<one-to-many entity-name="Item"/>
</bag>

</class>

</hibernate-mapping>



where Blog and Item are genuine Ruby classes. The nice part is that I haven't touched any existing Hibernate or JRuby code.


The plan is to package the things I already have (still need to write more tests to show what is working) and put it on SourceForge or Google Code to get some feedback from JRuby and/or Hibernate people. (I can very well imagine I've made things to complex where simpler solutions exist out-of-the-box.) After that it's time to start looking at ways to get rid of the XML mapping files by writing a friendly Ruby interface around the Hibernate details.


I hope that after some time this project will be stable/useful enough to be part of JRuby Extras at RubyForge.

Monday, July 23, 2007

ActiveHibernate: First Steps

Things are going smoother than I expected. Hibernate 3 already supports the use of dynamic maps and XML documents (these are alternative entity-mode's in Hibernate lingo) through the tuplizer mechanism. By extending Hibernate's AbstractEntityTuplizer class it is remarkably simple to let Hibernate work directly with instances of IRubyObject. Features like inheritance and many-to-one relations seem to work fine. (Haven't tried components and proxies yet.)

Now I'm trying to get collection mapping working (one-to-many). Hibernate wraps the user's collection (which would be a Ruby Array in our case) by its own implementation (of some java.util collection interface like java.util.List when dealing with POJOs) to track additions/removals and to support lazy collection loading. Customizing this is also nicely supported by Hibernate through user collection types. For this we need a wrapper that looks (walks, swims and quacks) like an Array to the Ruby code, and implements org.hibernate.collection.PersistentCollection to keep Hibernate happy on the Java side. I haven't found any other solution than to write a JRuby Java extension (by implementing JRuby's BasicLibraryService interface) to create a RubyObject subclass named PersistentRubyArray (to stay in line with the Hibernate naming convention) that wraps a RubyArray instance.

Anyway, it's fun to manipulate Ruby objects from within Java like puppets on a string, and to see how it all fits naturally with Hibernate.

Wednesday, July 18, 2007

JRuby + Hibernate = ActiveHibernate?

A couple of months ago, Ola Bini coined the idea of ActiveHibernate as an extra option when running Rails on JRuby (complementary to ActiveRecord-JDBC). After some debug sessions through the Hibernate and JRuby code I have convinced myself that this is indeed a nice and feasable project to start (or try to, at least). As Ola mentioned there are two parts to this:
  1. Configure/tweak Hibernate to let it work directly with the org.jruby.RubyObject class. I'm already impressed by the clean internal design of the Hibernate code, and the possibility to plug in custom implementations of Hibernate interfaces through the hbm.xml mapping files.
  2. Provide a Rubyish interface to the Hibernate configuration and functionality, following the fine Ruby on Rails tradition.
Point one seems the hardest to me, as I would like to keep the number of changes to org.hibernate (and org.jruby) code very low. None if possible (?). For the second point, ActiveRecord, Grails' O/R mapper (GORM) and Hibernate Annotations can serve as examples to learn from. I'm also looking forward to IronRuby to see if it could be married to NHibernate in a similar way.

As soon as I have something up and running I'll post the code to SourceForge, or RubyForge, or ... What would be the most appropriate hosting site for this kind of project?