Thursday, 28 January 2016

ColdFusion: help with clarifying if an issue exists with CF's ORM implementation

If you know something about Hibernate and/or using ColdFusion's wrapper around same, perhaps you could cast your analytical eye over this, and help determine whether Mingo has - as it seems - found a bug in it, or whether Himavanth has some basis to what he's saying, and it's not just a case of him (willfully choosing to ~ ?) not understanding what Mingo is saying, and there's actually no problem. Can you guess which side I come down on?

Here's the detail:

4024472: ORM entities are incorrectly created when using single table inheritance with mappedSuperClass

Problem Description:

When you have a base component (base.cfc) with MappedSuperClass set to true, a
persisted component (animal.cfc) inheriting from that and another (dog.cfc)
inheriting from that one ColdFusion throws an exception (a Hibernate one).
To make this bug more fun, CF doesn't always throw this exception.

The reason why this happens becomes clear when you set
this.ormsettings.savemapping=true and take a look at the hbmxml files.

The XML in dog.hbmxml contains the fields from base.cfc:
<property name="name" type="string"><column name="name"/></property>

Steps to Reproduce:

Use the files included with this bug [I'll include 'em inline here].

// base.cfc
component mappedSuperClass="true"
  property fieldType="id" name="id" generator="increment";
  property fieldType="column" name="name";

// animal.cfc
component extends="base" persistent="true" table="animal" discriminatorColumn="type"
  property fieldType="column" name="isAlive" type="boolean" default=true;

// dog.cfc
component extends="animal" persistent="true" table="animal" discriminatorValue="dog"
  property fieldType="column" name="furColor" default="brown";

Actual Result:

An exception: Repeated column in mapping for entity: {entity-name} column: {column-name} (should be mapped with insert="false" update="false")

Expected Result:

Correctly generated hibernate entities.

Any Workarounds:

You can write your own .hbmxml files to work around the problem.

Further information

For clarity: the dog entity gets the following HBM XML generated:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "">
<hibernate-mapping default-cascade="none" default-access="property" default-lazy="true" auto-import="true">
 <subclass discriminator-value="dog" entity-name="dog" extends="cfc:18502eb2916b8041cf1e.animal" lazy="true" name="" dynamic-update="false" dynamic-insert="false" select-before-update="false">
  <property name="name" type="string" unique="false" optimistic-lock="true" lazy="false" generated="never">
   <column name="name" />
  <property name="furColor" type="string" unique="false" optimistic-lock="true" lazy="false" generated="never">
   <column name="furColor" />

Notice the extra name property, that's not supposed to be there, because that should be inherited from the animal class.

My knowledge of ColdFusion's ORM is pretty theoretical as I've never used it beyond testing it, and my knowledge of Hibernate is scant (I've scanned a Hibernate book whilst testing the initial ColdFusion 9 implementation).

The most telling thing is that Lucee does what Mingo expects, and it works. That kinda suggests ColdFusion has got it wrong. It would seem too coincidental that Mingo's expectations are off, and it just so happens Lucee's implemented things in such a way that match Mingo's expectations. Occam's Razor 'n' all.

So perhaps you lot can eyeball this and the rest of the detail in Mingo's ticket, and offer your input?