openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nibbler <>
Subject Re: Help - Single table inheritance not working with one-to-many collection
Date Mon, 08 Dec 2008 19:51:55 GMT

Hi Jeremy,
Thanks for the reply.  Ouch, I made a mistake in the code above; the Test
class does have the @Entity annotation.  The Test superclass should be
abstract (didn't fix the problem).  Also, I'm not sure I was totally clear
in my description, so please allow me to restate.

So the problem again is that openjpa is ignoring the single-table
inheritance strategy when mapping a one-to-many collection (where the "many"
is using the inheritance).

I have an abstract Test superclass and two child classes, TestChild1 and
TestChild2.  The Test classes share fields 'id' and 'columnA'.  They can
also map many-to-one with a ContainingObject (yikes another mistake, the
'siteId' field should actually be the containingObjId/containing_obj_id that
provides the mapping.  Doesn't change the general gist, though).  TestChild1
adds a 'columnB' field.

I want to use single table inheritance so I have one table in the database. 
I need a discriminator column, so I add one, 'discriminator':

id long,
containing_obj_id long,
column_a varchar2(30),
column_b varchar2(30),
discriminator varchar2(1)

TestChild1 will use 'S' as it's discriminator value, and TestChild2 will use
'D' (my real classes were using an id column that is null in the case of one
class and not null in the other, but openjpa can't use null as a
discriminator value so I need to add the column.  But that's another

Anyway, my understanding of the docs is that I create the Test entity, and
then subclass it with the Testchild1 and TestChild2.  The Test entity is a
MappedSuperclass and controls the inheritance type (single table) and
discriminator column.  Then I add the discrimator value annotations to the
child classes and I should be good.

It works fine with Queries, but not with the one-to-many relationship in
ContainingObject: I get all of the Test objects in the table for that CO. 
It seems that openjpa, when getting the TankSource collection from the
ContainingObject, is ignoring the inheritance strategy.

Thanks again for your reply,

Jeremy Bauer wrote:
> Hi,
> I think the problem may be related to the use of MappedSuperclass on the
> base class.  Is your intent to create an entity inheritance hierarchy?
>  (This appears to be the case since you've specified an inheritance type
> and
> discriminator.)  If so the intent of mapped superclass is to map the
> superclass persistent information into the subclass entity table.  If you
> want a true inheritance hierarchy you should tag your Test class with
> @Entity instead of @MappedSuperclass.
> I haven't verified, but OpenJPA may be getting confused by the @Table
> annotation on the mapped superclass and is storing both types of entities
> in
> a single table.  Normally, each entity would map to its own table and that
> table would contain its persistent information and the persistent
> information stored in the mapped superclass.
> Hope this helps,
> -Jeremy
> On Fri, Dec 5, 2008 at 7:37 PM, nibbler
> <
>> wrote:
>> Hi,
>> I'm having trouble with single table inheritance and a one-to-many
>> relationship.  Specifically, I have two Entities that subclass from a
>> superclass using single table inheritance.  I have another Entity that
>> has
>> a
>> one-to-many relationship with one of the subclasses.  Using a simple
>> Query,
>> they behave properly, I get one subclass or the other.  But when
>> accessing
>> one of them through the container's one-to-many relationship, I get a
>> collection containing objects of both classes.
>> My classes basically look like this:
>> // This is the superclass.
>> @MappedSuperclass
>> @Table(name="test_table")
>> @Inheritance(strategy=InheritanceType.SINGLE_TABLE
>> @DiscriminatorColumn(name="discriminator")
>> public class Test {
>>  @Id
>>  @Column name="id_column"
>>  protected long idColumn;
>>  @Basic
>>  @Column(name="column_a")
>>  protected String columnA;
>>  @Basic
>>  @Column (name="site_id")
>>  protected long siteId;
>>  // Here's the link to the containing Entity.
>>  @ManyToOne (fetch=FetchType.LAZY)
>>  @JoinColumn (name="containing_obj_id")
>>  private ContainingObject co;
>> ...
>> }
>> // This is the first child.
>> @Entity
>> @DiscriminatorValue("S")
>> public class TestChild1 extends Test {
>>  @Basic
>>  @Column (name="column_b")
>>  private String columnB;
>> ...
>> }
>> // Second child.
>> @Entity
>> @DiscriminatorValue("D")
>> public class TestChild2 extends Test {
>>  // This class doesn't have any unique properties.
>> }
>> // This class contains the one-to-many.
>> public class ContainingObject {
>> ...
>>  // This is supposed to map a collection of TestChild1 objects.
>>  @OneToMany (mappedBy="co")
>>  private Set<TestChild1> testChildren = new HashSet<TestChild1>();
>> ...
>> }
>> Okay, so let's say I have 3 TestChild1 and 2 TestChild2 rows in
>> test_table
>> for a given ContainingObject. this works:
>>  Query q = em.createQuery("select test1 from TestChild1 test1 where
>> containing_obj_id = 100");
>>  List<TestChild1> list = (List<TestChild1>)q.getResultList();
>>  System.out.println("There are " + list.size() + " testChild1 objs");  //
>> But this doesn't work:
>>  // I've retrieved a ContainingObject 'co' with containing_obj_id of 100.
>>  Set<TestChild1> children = co.getTestChildren();
>>  System.out.println("There are " + children.size() + " testChild1 objs");
>> // THIS WILL SHOW all 5.
>> I have tried to put the many to one relationship in the TestChild1 class
>> (just to test) and that didn't work either.  What am I missing?
>> Thanks in advance!
>> --
>> View this message in context:
>> Sent from the OpenJPA Users mailing list archive at

View this message in context:
Sent from the OpenJPA Users mailing list archive at

View raw message