tags:

views:

302

answers:

1

Is it possible to configure Hibernate to store a component class in a separate table?

Take the following example:

<class name="test.ClassA">
   <property name="propA"/>
   <component name="componentProp" class="test.ClassB">
      <property name="propB"/>
   </component>
</class>

This maps to a table called MyClass with two columns propA and propB. What I want is to map the properties of the component to a table called ClassB.

What I don't want to do is configure ClassB as an entity in itself (it has no meaningful identity outside of ClassA), so that rules out a normal association. Also, I cannot modify the object model (it's generated code), so I can't introduce an ID property to ClassB.

This seems to be a gap in Hibernate's functionality - the <component> mapping performs "multiple-classes-to-one-table", and <join> does "one-class-to-multiple-tables", but oddly there's no apparent way of doing "multiple-classes-to-multiple-tables", without resorting to entity associations.

My rationale for wanting this is that I want my DB schema to resemble the object model as closely as is practical, and that includes separate tables for the ClassB component. I understand that this wouldn't scale - you couldn't do nested components, for example, but this isn't a problem in this particular situation.

+2  A: 

You can use <join> and <component> together, or did I misunderstand your question?

<class name="test.ClassA">
  <property name="propA"/>

  <join table="ClassB">
    <key column="ClassA_id" />
    <component name="componentProp" class="test.ClassB">
      <property name="propB"/>
    </component>
  </join>

</class>

While you (obviously) do need a foreign key, it does not have to be mapped in object model. Details on join are here - provided for completeness only, I know you know where to get them from :-)

Documentation at the above link does not explicitly say anything about mapping components within joins, but DTD does allow it and I've had it working in 3.1, so I'm pretty sure it still works fine. Don't know how (or whether it's possible) to map this with annotations, though.

ChssPly76
Ah, that looks like just what I need, thanks for that. I'll take her out for a spin and see if it's the ticket.
skaffman
I found this technique documented in section 8.1.3 of "Java Persistence with Hibernate". Looks sound. Thanks again.
skaffman
Thanks. I somehow managed to never read that book :-)
ChssPly76
I used the join and component together but it result in hibernate trigger the join query event i add the fetch="select" How can i make the component lazy init ?
robinmag