openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jeremy Bauer" <techhu...@gmail.com>
Subject Re: Help - Single table inheritance not working with one-to-many collection
Date Mon, 08 Dec 2008 21:07:30 GMT
Mike,
I think I understand the issue, but I apologize in advance if I've missed
your point (again).  :-)

Tagging a superclass with @Entity and @MappedSuperclass is not typical.
 MappedSuperclass does not define an entity inheritance hierarchy - it is an
strategy to map a table to a class inheritance hierarchy.  MappedSuperclass,
by definition, will use separate tables for each entity subclass, which is
contradictory to the single table inheritance strategy you've defined.

Try removing @MappedSuperclass from 'Test'.  OpenJPA should determine that
Test is an entity superclass of TestChild1 and TestChild2 and that you want
single table inheritance  (entity state of TestChild1 and TestChild2 stored
in the test_table).  Discriminator values will be used appropriately.

I haven't verified, but if you've tagged Test with @Entity and
@MappedSuperclass you may be getting some sort of hybrid behavior.  Some
things may appear to work, some may not.  If you remove @MappedSuperclass
(and have Test tagged with @Entity) and it still doesn't work, it sounds
like a bug...

-Jeremy

On Mon, Dec 8, 2008 at 1:51 PM, nibbler <Michael.Schneir@verizonwireless.com
> wrote:

>
> 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':
>
> test_table(
> 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
> matter).
>
> 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,
> -Mike
>
>
> 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
> > <Michael.Schneir@verizonwireless.com
> >> 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");
>  //
> >> THIS WILL SHOW THERE ARE 3.
> >>
> >> 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:
> >>
> http://n2.nabble.com/Help---Single-table-inheritance-not-working-with-one-to-many-collection-tp1620948p1620948.html
> >> Sent from the OpenJPA Users mailing list archive at Nabble.com.
> >>
> >>
> >
> >
>
> --
> View this message in context:
> http://n2.nabble.com/Help---Single-table-inheritance-not-working-with-one-to-many-collection-tp1620948p1630607.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message