openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Fay Wang <fyw...@yahoo.com>
Subject Re: Help - Single table inheritance not working with one-to-many collection
Date Mon, 08 Dec 2008 22:20:34 GMT
Hi Mike,
   I could not reproduce your problem. I used your entity definitions with the following modification:
   (1) put @Entity to the Test class 
   (2) made Test class an abstract class, 

  After the insert, my table has 5 rows in it:

select id_column, CONTAINING_OBJ_ID from test_table

ID_COLUMN            CONTAINING_OBJ_ID
-------------------- -----------------
                   1                 1
                   3                 1
                   4                 -
                   2                 1
                   5                 - 

   I then tested with the following:

       ContainingObject co = em.find(ContainingObject.class, 1);
       Set<TestChild1> children = co.getTestChildren();
       System.out.println("There are " + children.size() + " testChild1 objs");  // THIS WILL
SHOW all 5.


   The JDBC trace shows the push-down sql as:

1191  inheritance  TRACE  [main] openjpa.jdbc.SQL - <t 1094861122, conn 910046782> executing
prepstmnt 1434473856 SELECT t0.id_column, t0.discriminator, t0.containing_obj_id, t0.column_a,
t0.site_id, t0.column_b FROM test_table t0 WHERE t0.containing_obj_id = ?  [params=(int) 1]


     and I got 3 objects back. Which revision are you using? can you get the jdbc trace?

Regards,
Fay



--- On Mon, 12/8/08, Jeremy Bauer <techhusky@gmail.com> wrote:

> From: Jeremy Bauer <techhusky@gmail.com>
> Subject: Re: Help - Single table inheritance not working with one-to-many collection
> To: users@openjpa.apache.org
> Date: Monday, December 8, 2008, 1:07 PM
> 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
View raw message