How should Ribs definitions look?


I am currently sitting with Ribs, trying to decide how the definitions for associations should look like. I’ve also decided that I don’t want to use the current scheme for properties either. I also have some interesting constraints. First, I do not want to evaluate the block using instance_eval, so introducing nice method_missing hooks in the block context is out (so I can’t do anything like “has n” as DataMapper). Also, all definitions need to be able to take additional parameters in a hash. So something like “rib.has * :Posts” won’t work either.

I have come up with something that I’m reasonably happy with. It’s quite terse but definitely readable. It doesn’t pollute any namespaces. And hopefully it will only be used when the model need to differ from the conventions. I’m thinking about taking conventions a step further with Ribs and automatically try to figure out associations based on naming and foreign keys – but I haven’t decided about that yet.

All of these examples are supposed to be executed inside the Ribs! block, with r being the Rib parameter. I’ve decided to allow the table name as a parameter to the Ribs! method call instead of being something you set inside.

First of all, setting which property/properties are a primary key, I’m thinking about one or more of these alternatives – where track_id is the property name:

r.track_id :primary_key
r.track_id :primary_key => true
r.track_id = :primary_key
r.track_id.primary_key!

I’m skittish about the track_id= alternative, but the others I think can coexist quite well.

The next thing is to handle the mapping from one property name into a different column name (if no column name is specified, the property name will be used, of course):

r.title :column => :track_title
r.title.column = :track_title

Nothing very extraordinary here. I would probably like to have both alternatives here.

The next one is more interesting. I haven’t yet decided how to handle specifying primitive types. This code is supposed to handle the case that in ActiveRecord are covered with has_one and belongs_to. I don’t really see why they have to be different, really, so I’m thinking about doing something like this:

r.blog :is_owner
r.blog :is => Blog

I’m skittish about :is_owner, but it also feels slightly icky to have to specify the type of all single associations. This is definitely an area I would like to have some good ideas about.

Finally we come to the one-to-many and many-to-many associations. What makes this different is that I can have both a Set and a List (and also Map) since Hibernate handles these for me:

r.comments :list_of => Comment
r.comments :set_of => Comment
r.comments :is_set
r.comments :is_list

Once again I’m not sure how to handle it in such a way that you don’t have to write the name of the other entity in all definitions.

Anyway, this is what I currently have. I would appreciate innovative ideas here – especially if they are innovative within the constraints I’ve set for myself.



Ribs available from Gems


Ribs is now available from Gems. You can install it using this command:

jruby -S gem install ribs

Much pleasure, and do give your comments and ideas to me.



Announcing Ribs 0.0.1


I am extremely pleased to announce the first release of Ribs.

Ribs is a library for JRuby, that allows you to persist Ruby objects using Hibernate. Some time ago I wrote about ActiveHibernate. I have now decided to implement this myself, and the result is the Ribs project.

The first release is quite minimal in scope. You can define and work with models that have primitive values only – there is no support for associations. You can find, create, update and delete model objects. All of this uses Hibernate and JDBC.

To get started, you just define that an object is to be a Ribs model:

class Artist
  Ribs!
end

Once that’s done, you can start working with it.

Of course, this is just the beginning. I have a quite long list of things I’d like to have in the project, but I felt the need to release quickly and often to be more important than to implement everything first.

This release is not really for production usage, but I would appreciate if people tried it out and came with suggestions. The current planned features can be found in the PLAN file, in the git repository.

More documentation can be found here: http://olabini.com/projects/ribs/doc.
You can download the gem at: http://olabini.com/projects/ribs/downloads/ribs-0.0.1.gem.
The git repository is at: git://github.com/olabini/ribs.git.

Ribs will soon be available in the regular gem repositories – as soon as my Rubyforge project has been approved.

The project is released under the MIT license.



Unexpected JRuby overload resolution


Had an interesting bug using Hibernate from JRuby today. Totally unexpected actually. Interestingly, it actually exposed a problem with dynamic dispatch when going into a static language. To a degree I guess it’s about getting our overload resolution more correct, but it seems like a general rule will be hard.

Basically, my problem was this. I was calling update() on org.hibernate.Session. Now, I used the version that take a String with the entity name, and the actually entity as the other parameter. So the signature update(String, Object) was the one I was aiming for. Sadly, things failed, and kept on failing. And I really couldn’t figure out why. I got this lovely error message: org.hibernate.MappingException: Unknown entity: java.lang.String. This problem can show up from several different reasons, so Google didn’t help.

And then, after tracing the calls for a bit, I finally understood. It just so happens that the default implementation of Session (called org.hibernate.impl.SessionImpl), have a few public update methods that are not part of the Session interface. One of them has the signature update(Object, Serializable). The first parameter is the object to update, and the serializable parameter is the id. JRuby was very helpful in choosing to call that method instead of the update(String, Object) one, since my entity happened to be serializable. Of course, this meant that Hibernate tried to persist a String, instead of my real object, and this fails. The workaround was simple in this case: just use the single argument version of update, since the entity name can be figured out from the object.

But in general these kind of problems will show up sometimes – it’s the price you pay for having an extremely flexible dynamic programming language, interfacing with a statically typed language. But we can improve the overload resolution, and also make it possible to control it more explicitly. I’m currently thinking that it might be a good plan to have some debug flags that will give you some output about overload resolution and things like that too. What do you think? How would you solve this in JRuby?



ActiveHibernate is happening


So, it seems someone stepped up to the challenge and started working on ActiveHibernate from me initial idea. The code got pushed online a while back and I have finally had the time to look at it. Over all it looks really nice.

Of course, it’s very early times. I’ve submitted some patches making the configuration aspect easier and more AcitveRecord like – but it’s going to be important to have access to all the features of Hibernate too. When in the balance, I don’t think we should aim for total ActiveRecord equivalence.

Read more here and find the Google Code project here.

I would encourage everyone interested in a merger between Rails and Hibernate to take a look at this. Now is the time to come with advice on how it should work, what it should do and how it should look like.



ActiveHibernate – Any takers?


This is a call for action. JRuby on Rails is getting more stable each day, and JRuby performance is consistently improving. This means that JRuby on Rails is well on the path of becoming a viable platform for several kinds of web development.

ActiveRecord-JDBC is central to this, and it’s a good project and works very well. Within the limitations of ActiveRecord, of course. So, I’m thinking (and this is by all means not a new thought), that I would like to have the rest of Rails, but using Hibernate as backend. With JRuby approaching 1.0 fast, ActiveHibernate seems like a neat project. The only problem is time. So why is ActiveHibernate tempting? Well, for all those situations where ActiveRecord really doesn’t fit; composite keys, complicated legacy systems. Or databases where you would like to use prepared statements for everything. Or get really nice speed.

What needs to be done? For it to be really useful, there are few points: First, a Hibernate extension that serializes and deserializes into RubyObjects. By doing it that way, there is no need to create Java bean classes. Secondly, provide all the useful help functionality around the Hibernate implementation, that AR users have gotten used to. This includes things like validations, automatic handling of updates and inserts, and is generally about doing a good Ruby interface around Hibernate. This also includes creating a good way of configuring Hibernate without having to resort to the XML. Maybe using YAML? Or a Ruby DSL? After that has been done, the final point is easy: get mind share and start doing applications with it! I for one know that I would like to use such a project!