Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] two instances of same object in an indirectList ?

I'm using field access (annotations on the field declarations, not on the methods), but I do have extra logic in the setter methods for handling the maintenance of the collections on the other side of the relationship as I illustrated in my last mail.  The link you pasted wouldnt apply to my case would it, since my annotations are on the variables themselves?

Thanks


----- Original Message ----
> From: James Sutherland <jamesssss@xxxxxxxxx>
> To: eclipselink-users@xxxxxxxxxxx
> Sent: Wednesday, January 7, 2009 7:59:51 AM
> Subject: Re: [eclipselink-users] two instances of same object in an indirectList ?
> 
> 
> Are you using field access or property access in your mappings?  If you are
> using property access this could cause the issue, using property access with
> side-effects in your get/set methods can corrupt your object model.  If you
> want to use property access, ensure you use get/set methods that have no
> side-effects.
> 
> See,
> http://en.wikibooks.org/wiki/Java_Persistence/Mapping#Odd_behavior
> 
> 
> 
> Phillip Ross-3 wrote:
> > 
> > 
> > 
> >> In EclipseLink Collection will default to IndirectList when reading from
> >> the
> > 
> >> database if the relationship is LAZY.  If it is EAGER it will default to
> >> Vector.  If it were of type Set, it would default to IndirectSet or
> >> HashSet.
> > 
> > That makes sense, and that is what I was seeing, so that is good.
> > 
> > 
> >> My guess as to what you are seeing is that in the container each
> >> transaction
> >> is a new persistence context, so you get a new clone in each transaction
> >> that has the IndirectList.  Outside the container the persistence context
> >> is
> >> extended as long as the EntityManager exists, so when you do a find() you
> >> get the same object that you originally persisted, and I assume your
> >> constructor is setting it to a HashSet.  If you create a new
> >> EntityManager
> >> or refresh() the object outside the container you will get the
> >> IndirectList.
> > 
> > The code is a pretty simple test.  It involves two stateless session
> > beans.  One is a "service" bean
> > and the other is the "persistence fascade" bean.  They both use default
> > container managed transactions
> > without any explicit transaction attributes, and the fascade has its
> > entity manager injected via a
> > @PersistenceContext annotation.  The fascade is then injected into the
> > service bean with an @EJB annotation.
> > 
> > The purpose of the method of the particular service bean being tested is
> > to count the number of
> > related Opening entities that a specific OpeningStatus or Department
> > entity may be related to.  There are
> > two different methods, one for status and one for department but I'll just
> > talk about one for the purposes
> > of this explanation.  The method simply takes the OpeningStatus, passes it
> > to the fascade method which takes
> > the id value of the OpeningStatus, uses the entity manager in the fascade
> > to find a managed instance of the
> > OpeningStatus, then return it back to the service method, and the service
> > method calls the getOpenings
> > method to get the collection of related openings, then the size() method
> > to return the size of that collection.
> > I know this could be done alternatively with a single jpa query but let's
> > not get into that now.
> > 
> > So, in my test, the transaction should begin at the service bean method
> > invocation and continue through
> > into the fascade, the instance of OpeningStatus should stay
> > managed/attached, return the collection, and
> > the size should correctly be calculated since the related openings can be
> > fetched lazily.  So the final size
> > is determined within a single transaction and returned back to the caller
> > (the test code).
> > 
> > Also, you are correct, the constructors for OpeningStatus and Department
> > initialize the property with a HashSet.
> > 
> > Is my explanation clear and my logic sound?
> > 
> > 
> > 
> >> As to why you have duplicates, this is odd, it means you have duplicate
> >> rows
> >> in your database, or you added the object to the collection twice, which
> >> is
> >> not good.  You should not add the object to the collection if it is
> >> already
> >> contained in it.
> > 
> > I definately do not have duplicate rows in the database... there is a
> > primary key on the id fields of each entity
> > and setting FINEST log level in persistence.xml shows only a single
> > insert, so I know the state of the database
> > is valid, consistent, etc.
> > 
> > I definately do not add the Opening to the collection properties of
> > OpeningStatus or Department entities more
> > than once since I have rigid patterns for relating.  I always use the
> > setter method on the Opening to assign an
> > OpeningStatus or Department to an Opening, and that setter contains the
> > logic to managed the relationship in
> > both directions.  Here's example code:
> > 
> > public void setStatus(OpeningStatus status) {
> >         if (this.status != null) {
> >             this.status.getOpenings().remove(this);
> >         }
> >         if (status != null) {
> >             Collectionopenings = status.getOpenings();
> >             if (openings != null) {
> >                 openings.add(this);
> >                 this.status = status;
> >             }
> >         }
> >     }
> > 
> > public void setDepartment(Department department) {
> >         if (this.department != null) {
> >             this.department.getOpenings().remove(this);
> >         }
> >         if (department != null) {
> >             Collectionopenings = department.getOpenings();
> >             if (openings != null) {
> >                 openings.add(this);
> >                 this.department = department;
> >             }
> >         }
> >     }
> > 
> > 
> > If you can find a bug in that code which shows the entities being added
> > twice (or any bug at all
> > for that matter) I'd greatly appreciate it!
> > 
> > I use the same pattern in about 6 or 7 other entities with one-to-many
> > relationships and it works
> > fine, but I just cant find the difference for these.  I've since worked
> > around the entire issue by explicitly
> > changing the types from Collection to Set, and changing all of the queries
> > to push the returned Lists
> > with duplicates into Sets.  This works, but still concerned about the
> > duplicates being returned in the
> > lists returned by the queries :(
> > 
> > Thanks!
> > - Phillip
> > 
> > 
> > 
> > 
> > 
> > 
> >> 
> >> 
> >> 
> >> Phillip Ross-3 wrote:
> >> > 
> >> > HI Tom, thanks for the response.  I can certainly attempt to post the
> >> > definition.
> >> > 
> >> > On one side of the relationship the entity has two properties as
> >> follows:
> >> > 
> >> > 
> >> 
> @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
> >> >  private Department department;
> >> > 
> >> > 
> >> 
> @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
> >> > private OpeningStatus status;
> >> > 
> >> > While on the other side, the properties are as follows:
> >> > 
> >> > @OneToMany(mappedBy = "department",
> >> > cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
> >> > private Collectionopenings;
> >> > 
> >> > and
> >> > 
> >> > @OneToMany(mappedBy = "status",
> >> > cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
> >> > private Collectionopenings;
> >> > 
> >> > 
> >> > I've worked around the issue for now by redefining all of the
> >> Collection
> >> > based properties as Set based instead.  Luckily they all fit within the
> >> > Set semantics so I'm happy to leave them that way.  But I'm still
> >> > wondering why the underlying Lists contain duplicates, or... are lists
> >> at
> >> > all rather than sets.  I should mention again that the query involves
> >> > invoking find() on an entity manager with either a Department or
> >> > OpeningStatus and both of those have Collection based relational
> >> > properties mapped to OpeningStatus and Department.  But the underlying
> >> > Collection is an IndirectList (when running inside the container) and a
> >> > HashSet when running outside.
> >> > 
> >> > Thanks
> >> > - Phillip
> >> > 
> >> > 
> >> > 
> >> > ----- Original Message ----
> >> >> From: Tom Ware 
> >> >> To: EclipseLink User Discussions 
> >> >> Sent: Tuesday, January 6, 2009 9:30:03 AM
> >> >> Subject: Re: [eclipselink-users] two instances of same object in an
> >> >> indirectList ?
> >> >> 
> >> >> Hi Phillip,
> >> >> 
> >> >>   I am a bit surprised that you are getting a TransparentList.  I
> >> would
> >> >> expect a 
> >> >> TransparentSet.  Can you post the definition of the relationship?
> >> >> 
> >> >> -Tom
> >> >> 
> >> >> Phillip Ross wrote:
> >> >> > Hi all... I'm looking for some quick ideas.
> >> >> > 
> >> >> > Was wondering if someone could quickly think of a few things for me
> >> to
> >> >> check 
> >> >> out with a problem I'm having.  I have a pair of entities with
> >> OneToMany 
> >> >> relationships to a third entity.  If I return an instance with the
> >> entity 
> >> >> manager using find and PK id, I get an instance and the Collection
> >> >> contains two 
> >> >> items.  Both items are references to the same related object... exact
> >> >> hashCodes, 
> >> >> etc.  When I run outside the container, the Collection is a HashSet
> >> and
> >> >> it only 
> >> >> contains one reference to the related item due to the Set semantics
> >> which
> >> >> works 
> >> >> great... but inside the container the Collection is an eclipselink
> >> >> specific 
> >> >> IndirectList but with dups of the same item.
> >> >> > 
> >> >> > So, might there be something I'm doing wrong that's creating the
> >> dups
> >> >> in the 
> >> >> indirect list?  I have several other similar OneToMany relations to
> >> other 
> >> >> entities and they don't exhibit the problem, but I've been racking my
> >> >> mind 
> >> >> trying to figure out if there is something I'm missing here to get the
> > 
> >> >> dedup to 
> >> >> happen on the IndirectList.  There are several things I'm sure I could
> >> >> implement 
> >> >> myself to work around all of this and handle deduping and such, but
> >> I'm
> >> >> really 
> >> >> wondering why this duplication happens in the indirect list with these
> >> >> specific 
> >> >> entities and not with the other three or four other similarly
> >> patterned 
> >> >> OneToMany related entites.
> >> >> > 
> >> >> > Any ideas?  I'm using eclipselink 1.0.2, container is glassfish
> >> >> v2.1-b60e 
> >> >> (tried with earlier glassfish versions as well).
> >> >> > 
> >> >> > Thanks!
> >> >> > - Phillip
> >> >> > 
> >> > 
> >> 
> > 
> > 
> 
> 
> -----
> ---
> http://wiki.eclipse.org/User:James.sutherland.oracle.com James Sutherland 
> http://www.eclipse.org/eclipselink/
> EclipseLink ,  http://www.oracle.com/technology/products/ias/toplink/
> TopLink 
> Wiki:  http://wiki.eclipse.org/EclipseLink EclipseLink , 
> http://wiki.oracle.com/page/TopLink TopLink 
> Forums:  http://forums.oracle.com/forums/forum.jspa?forumID=48 TopLink , 
> http://www.nabble.com/EclipseLink-f26430.html EclipseLink 
> Book:  http://en.wikibooks.org/wiki/Java_Persistence Java Persistence 
> -- 
> View this message in context: 
> http://www.nabble.com/two-instances-of-same-object-in-an-indirectList---tp21297380p21330862.html
> Sent from the EclipseLink - Users mailing list archive at Nabble.com.
> 
> _______________________________________________
> eclipselink-users mailing list
> eclipselink-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/eclipselink-users



Back to the top