Tuesday, September 25, 2007

Subclasses with ActiveHibernate

Finally I resumed my work on ActiveHibernate. It now uses a XmlMarkup Builder and the visitor pattern to sort out the relationships between different persistent classes and to generate the mapping XML internally. This might sound like overkill, but even to get inheritance up and running it seemed like the only way to keep things maintainable. Anyway, the Ruby code

class Payment
include Hibernate
hattr_accessor :amount,:double
...
end

class CreditCardPayment < Payment
join_with_table do
hattr_accessor :creditCardType,:string
...
end
end

class ChequePayment < Payment
hattr_accessor :chequeNumber,:string
..
end

generates the mapping

<class name="Payment" table="PAYMENT">
<id name="id" type="long" column="PAYMENT_ID">
<generator class="native"/>
</id>
<discriminator column="PAYMENT_TYPE" type="string"/>
<property name="amount" type="double"/>
...
<subclass name="CreditCardPayment" >
<join table="CREDIT_CARD_PAYMENT">
<key column="PAYMENT_ID"/>
<property name="creditCardType" type="string" />
...
</join>
</subclass>
<subclass name="ChequePayment" >
<property name="chequeNumber" type="string" />
...
</subclass>
</class>


The <join/> construct in the CreditCardPayment mapping allows to combine the table-per-class-hierarchy and the table-per-subclass mapping strategies in one inheritance hierarchy. In the Ruby mapping DSL it can be nicely expressed with a class method (table name and key are optional arguments) and a block. The fact that a Ruby class definition is just ordinary Ruby code (with self referring to a Class object) opens a whole new world to the simple Java developer that I am.


In Subversion soon.