hibernate and component querying

Well here is some interestingness with querying for components using the 3.2.0cr5 version of hibernate. (FYI using accessor methods is the way the code was actually written. Direct references to properties in this example used just for clarity.)

Components in hibernate are objects that are represented in the database as a subset of columns with in their container. For example:

In the Java code:

class Foo {
    public Peanuts peanut;
    public int foo1;
    public Bar bar;
}

class Bar {
    public Peanuts peanut;
    public int bar1;
}

class Peanuts{
   public Foo foo;
}

     <class name="Foo">
         <many-to-one name="peanut"/>
         <property name="foo1"/>
         <component name="bar">
             <property name="bar1"/>
         </component>
    </class>

will result in a database table ‘FOO’ that looks like:

PEANUT, FOO1, BAR1

Now the problem I have is that I wanted to retrieve Bars. Using a PostLoadEventListener looking for Foo‘s, I wanted to fix up the reference Bar had to Peanuts, like this:


    public class FooPostLoadListener implements PostLoadEventListener {
        private static final long serialVersionUID = 1L;

        public void onPostLoad(PostLoadEvent event) {
            if ( event.getEntity() instanceof Foo) {
                Foo ts = (Foo)event.getEntity();
                ts.bar.peanuts = ts.peanuts;
            }
        }
    }

But of course the entity being loaded is a Bar not a Foo.

Now there is the possible use of the <parent> with in the Bar component. However, that means that a publically visible method is available that should never be used. (<parent> doesn’t have the ability to set the property using ‘field’ access).

The next step was creating a setParent(Foo) and a Foo getParent() on bar:


class Bar {
    public Peanuts peanut;
    public int bar1;
    public void setParent(Foo f) {
       peanuts = f.peanuts;
    }
    public Foo getParent() {
        return peanuts.foo;
    }
}

     <class name="Foo">
         <many-to-one name="peanut"/>
         <property name="foo1"/>
         <component name="bar">
             <parent name="parent"/>
             <property name="bar1"/>
         </component>
    </class>

Now this doesn’t work because the setParent() method is called before Foo has any of its fields instantiated. This actually makes a lot of since otherwise when you are reading in the result set, there is a lot of juggling to get the data ordered in the right way for what the code needs.

Unfortunately, inspite of all this rework at the end of it all, querying for a component returns the component without the parent Foo set. I was hoping that accessing the parent Foo via a call to getParent() would trigger a load of Foo but it doesn’t.

This entry was posted in hibernate. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *