Wednesday, 24 September 2008

Tables relationships

Lately I've been working quite hard on mapping the relationships between tables.
It seems to be a lot harder than I first thought, both because of the complexity of the task in itself and because of another limitation of Java.

Mantaining the relationships is hard because an ORM must, for every change made to an object, change the table directly mapped by that object and all the related tables (updating foreign keys or deleting children rows in varoius tables). Furthermore, when linking mapping objects together, the ORM must take care to update the corresponding tables only when and if it is necesary. Finding out when and which updates must be performed in an intelligent way is not always so obvious.

Another unforeseen problem is Java's inability to dynamically create fields. To be fair, this is a problem most compiled (or byte-code compiled) languages have.
In a scripting language (think about JavaScript or Ruby), you can dinamically add a field (or a method) to a class at runtime. This possibility gives an ORM a great deal of freedom and greatly improves the simplicity and terseness of its interfaces.
In Rails if a table A has a relationship with table B, The class representing table A will have a field b corresponding to an object of type B (or vice versa, depending on the relationship between the tables). This field does not need to be hard-coded into the class, it is dinamically inferred and added to the class, and that field can be used directly (i.e. a.b = "something" if a is of type A).
In Java this is not possible. Java does not permit a field to be added dinamically and this forces the design of the classes to be awkward (lists of related objects, with methods to access them...) and hard to read.

I'm trying to find a workaround for these problems that permits a nice interface, but I'm also trying to have a first working version to release (even if it is buggy and not pretty).

Friday, 8 August 2008

Static methods

One of the first things I had to consider when designing SimpleRecords was which methods the main class should have and wheter they should be static or not.

I wanted to have a behaviour similar to ActiveRecord's one:
  • You create a class, representing a database row, extending a base class
  • The new class inherits from the superclass all its database mapping business logic
  • The new class now has some instance methods to work with the row it represents (save, delete...) and some static methods to retrieve objects reading the DB table (find, create...)
This behaviour is granted by reflection and inheritance: the table name is inferred by the inherited methods (inheritance) from the derived class name (reflection). This permits to write a class mapping a database table in a very simple way (if the class does not need aditional business logic, all you have to do is create an empty class extending the RecordBase superclass).

Come Java, and its implementation of inheritance. In Java static methods are not inherited. A derived class can use its superclass static methods, but these methods still reside in the superclass. The problem with this approach is that if you try to get the name of the current class or one of its fields, via reflection, inside a static method, you will always get the name or the field of the class which defined the static method and not the name of one of its derived class that is using said method.

This leads to an important decision about how to implement the Active Record pattern. Basically I had two possibilities:
  1. Break the design pattern and any basic logic behind a class, having only instance methods
  2. Use static methods, passing them a parameter to be able to identify the actual class we are using.
The first method permits a syntax similar to the original Rails ActiveRecords, but breaks the logic behind the Class. For example to get an object from the database you have to create an empty object, call its find() method that returns another object, this representing the real mapping with the database row. Clearly the method should be static.

On the other hand, the second approach keeps the Class logic intact, but needs an extra parameter, containing the actual class informations, for every static method inside the base class.

Instead of choosing one approach instead of the other, I decided to keep them both, and provide two superclasses from which to inherit: one providing static methods and one providing instance methods. If and when one approach becomes better than the other, I will ditch the inferior one.

About SimpleRecords

I recently started studying Ruby on Rails, and I was really impressed by its ActiveRecords component.

I am currently working as a J2EE developer, with all the horribly complex and intricate methods and patterns to access a database. When I first saw an active record-powered class I was deeply impressed. It was so totally different from the way I am used to think about Database access, that I thought I had to use it in my day-to-day work.

So I started searching for a Java implementation of this pattern, but it seems that at the moment there are very few options (activeobjects, jactiverecord, arjava, activemapper) and in addition none of the projects has released anything usable.

This pushed me into loking a bit deeper into the ActiveRecord pattern, and I found out it was not so difficult to create a basic implementation (no error handling, no table relationships...) of the pattern in Java. I then tried to insert this spagetti-code class into a branch of an actual project I'm working on, and up until now it's working quite well.

I want now to give this little experiment space to grow and dedicate to it some of my time, so that's the reasons behind the SourceForge project. On this blog I will post ideas, news, considerations arising from this project.