persistence@glassfish.java.net

Re: Many-To-Many on JavaSE Collection returning null

From: David Harrigan <dharrigan_at_gmail.com>
Date: Wed, 4 Apr 2007 14:03:39 +0100

Hi Tom, thanks for replying (you're probably v.busy :-) )

Doesn't work. Here's the code:

        Item parent = itemFactory.getItem("Parent");
        Item child1 = itemFactory.getItem("Child 1");
        Item child2 = itemFactory.getItem("Child 2");
        Item child3 = itemFactory.getItem("Child 3");
        final Set<Item> children = new HashSet<Item>();
        final Set<Item> child1Items = new HashSet<Item>();
        final Set<Item> child2Items = new HashSet<Item>();
        final Set<Item> child3Items = new HashSet<Item>();
        children.add(child1);
        children.add(child2);
        children.add(child3);
        child1Items.add(parent);
        child2Items.add(parent);
        child3Items.add(parent);
        parent.setRelatedItems(children);
        child1.setItems(child1Items);
        child2.setItems(child2Items);
        child3.setItems(child3Items);
        em.getTransaction().begin();
        em.persist(parent);
        em.getTransaction().commit();
        assertEquals("Should not be '0'", true, parent.getItemId() != 0);
        assertEquals("Should not be '0'", true, child1.getItemId() != 0);
        assertEquals("Should not be '0'", true, child2.getItemId() != 0);
        assertEquals("Should not be '0'", true, child3.getItemId() != 0);

        // set all to null

        final int parentItemId = parent.getItemId();

        parent = null;
        child1 = null;
        child2 = null;
        child3 = null;
        children.clear();

        parent = em.find(Item.class, parentItemId)

        children.addAll(parent.getRelatedItems());

        assertEquals("Size should be 3", 3, children.size());

It fails on the assert size == 3. Returns 0.

I assume now that I'm wiring up both parts? The database looks the
same as before. Interestingly enough (but maybe just a red-herring) is
that I've set the logging to FINEST, yet I'm getting no SQL back, just
these lines (note the last line, it's doing a ReadQueryObject - does
this suggest some type of caching??? - it's not going off to the db??)

[TopLink Fine]: 2007.04.04
12:57:20.459--ClientSession(19167401)--Connection(31742556)--Thread(Thread[main,5,main])--INSERT
INTO ITEM (ITEMID, MODIFIEDTIME, EXPIRYTIME, ITEMTYPE, RELEASETIME,
DESCRIPTION, SOURCEFILENAME, COPYRIGHT, LOCATIONURI, AGECODE,
SERVICEID, AUTHOR, CREATEDTIME, THIRDPARTYID, TITLE, TAGS_TAGSID,
PROVIDER_PROVIDERID, RESTRICTION_RESTRICTIONID) VALUES (?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        bind => [4, 2007-04-04 12:57:20.396, 2007-04-04 12:57:20.396, 0,
2007-04-04 12:57:20.396, A descriptive entry, me.mpg, (C) Copyright
2007, http://www.java.net, 18, 1, David Harrigan, 2007-04-04
12:57:20.396, BBC01, Parent, 5, 7, 7]
[TopLink Finest]: 2007.04.04
12:57:20.460--UnitOfWork(7544464)--Thread(Thread[main,5,main])--Execute
query DataModifyQuery()
[TopLink Fine]: 2007.04.04
12:57:20.460--ClientSession(19167401)--Connection(31742556)--Thread(Thread[main,5,main])--INSERT
INTO ITEMRELATEDITEM (relatedItems_ITEMID, items_ITEMID) VALUES (?, ?)
        bind => [5, 4]
[TopLink Finest]: 2007.04.04
12:57:20.465--UnitOfWork(7544464)--Thread(Thread[main,5,main])--Execute
query DataModifyQuery()
[TopLink Fine]: 2007.04.04
12:57:20.466--ClientSession(19167401)--Connection(31742556)--Thread(Thread[main,5,main])--INSERT
INTO ITEMRELATEDITEM (relatedItems_ITEMID, items_ITEMID) VALUES (?, ?)
        bind => [6, 4]
[TopLink Finest]: 2007.04.04
12:57:20.466--UnitOfWork(7544464)--Thread(Thread[main,5,main])--Execute
query DataModifyQuery()
[TopLink Fine]: 2007.04.04
12:57:20.467--ClientSession(19167401)--Connection(31742556)--Thread(Thread[main,5,main])--INSERT
INTO ITEMRELATEDITEM (relatedItems_ITEMID, items_ITEMID) VALUES (?, ?)
        bind => [7, 4]
[TopLink Finer]: 2007.04.04
12:57:20.467--ClientSession(19167401)--Connection(31742556)--Thread(Thread[main,5,main])--commit
transaction
[TopLink Finer]: 2007.04.04
12:57:20.469--UnitOfWork(7544464)--Thread(Thread[main,5,main])--end
unit of work commit
[TopLink Finer]: 2007.04.04
12:57:20.470--UnitOfWork(7544464)--Thread(Thread[main,5,main])--resume
unit of work
[TopLink Finest]: 2007.04.04
12:57:20.471--UnitOfWork(7544464)--Thread(Thread[main,5,main])--Execute
query ReadObjectQuery(orange.media.service.model.Item

-=david=-



On 4/4/07, Tom Ware <tom.ware_at_oracle.com> wrote:
> Hi David,
>
> What happens if you change your code to do the following:
>
> Item parent = new Item();
> Item child = new Item();
> Item child2 = new Item();
>
> children.add(child);
> children.add(child2);
>
> child1Items.add(parent);
> child2Items.add(parent);
>
> parent.setRelatedItems(children);
> child1.setItems(child1Items);
> child2.setItems(child2Items);
>
> em.getTransaction().begin();
> em.persist(item);
> em.getTransaction().commit();
>
> The JPA specification dictates that you have to maintain both sides of bidirectional relationahips yourself.
>
> -Tom
>
>
>
> David Harrigan wrote:
>
> >Hi,
> >
> >Java 6 (update 1).
> >Glassfish v2 build = tracking cvs.
> >
> >Background:
> >
> >One class, doing a self-referential many-to-many (code has been cropped):
> >
> >@Entity
> >public Class Item {
> >
> > @Id
> > private int itemId;
> >
> > @ManyToMany(cascade = {PERSIST, MERGE, REFRESH})
> > @JoinTable("ITEMRELATEDITEM")
> > private Set<Item> relatedItems;
> >
> > @ManyToMany(mappedBy = "relatedItem")
> > private Set<Item> items;
> >
> >}
> >
> >If I then do:
> >
> >Item parent = new Item();
> >Item child = new Item();
> >Item child2 = new Item();
> >
> >children.add(child);
> >children.add(child2);
> >
> >parent.setRelatedItems(children);
> >
> >em.getTransaction().begin();
> >em.persist(item);
> >em.getTransaction().commit();
> >
> >All 3 entities get inserted into the database (assume ids, parent = 1,
> >child = 2 and child = 3)
> >
> >In the ITEMRELATEDITEM table, these rows exist:
> >
> >RELATEDITEMS_ITEMID ITEMS_ITEMID
> >2 1
> >3 1
> >
> >Okay, subsequentially, if I now do the following:
> >
> >parent = null;
> >child = null;
> >child2 = null;
> >
> >parent = em.find(Item.class, 1);
> >
> >I get back the Parent Item object, but, if I then do:
> >
> >parent.getRelatedItems()
> >
> >this returns an empty set - always.
> >
> >Even if I put FetchType.EAGER on the two annotated fields.
> >
> >If I try this within a container (GF, current cvs), it works, in that
> >getRelatedItems returns back a set with 2 items in it.
> >
> >Is there a problem with this in JavaSE?
> >
> >
> >-=david=-
> >
> >
> >
> >
>


-- 
PGP Key Id: E2BE72FC
Public Key: http://www.harrigan.info/public.asc