Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Adding/removing relations
Adding/removing relations [message #1089953] Mon, 19 August 2013 13:51 Go to next message
Neikius Mising name is currently offline Neikius Mising name
Messages: 43
Registered: April 2011
Member
Eclipselink 2.5, Glassfish 3.1.2.2, container managed context and in this case extended persistence context (but same happens also without the extended context).

I have a few @ManyToMany relations and something has me stumped.

When user starts editing an objects, the @Stateful EJB bean fetches the object editingObj and stores it.
editingObj = em.find(Obj.class, objId);


Now when user wants to add a related object a function fetches the related object relatedObj by id and checks if it is already present in the relation.
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
function a() {
// fetch
relatedObj = em.find(Obj.class, relObjId);

// check
if (relatedObj.getObjects().contains(editingObj) || editingObj.getObjects().contains(relatedObj)) 
 throw new EJBException("cannot add existing relatedobject");


Problem is object references from relation are not the same as object reference I get from em.find(). So the list of objects (relation) never contains the target object. I guess I am expecting too much and must check objectID field for identity...

Is there another way of finding out identity? How could I maintain a relation that won't get duplicated? I have a separate PK column in the intersecting table so relation can get inserted (unless I'd have set unique indices but I'd rather not have SQL exceptions in this case since it would show only after saving).

I know I can always check object's id's, but is there another nicer way of doing this in Eclipselink (jpa)?
Re: Adding/removing relations [message #1089966 is a reply to message #1089953] Mon, 19 August 2013 14:20 Go to previous messageGo to next message
Neikius Mising name is currently offline Neikius Mising name
Messages: 43
Registered: April 2011
Member
Ok, I think I've got it.

If I call another stateless EJB to fetch the object it returns a different reference. If I use em.find inside the stateful ejb bean (and within a method that is marked NOT_SUPPORTED for transactions) then I get the same references. I guess the other EJB has transaction set to REQUIRED by default and it returns another object reference since it is somehow outside of this context... my vocabulary here is worse than dregs so someone proficient in JPA talk might want to explain this. But I am quite sure this has something to do with transactions.

---

Ok I've tested it a bit more.

I was using
someEJB.getObject(id)

to get object.

This never gets the same object reference regardless of the getObject method @TransactionAttribute. The caller method has @TransactionAttribute(NOT_SUPPORTED) since I am working with extended persistence context and don't want this method to commit. I guess this is all as expected and specified somewhere. Hope this helps someone...

If I use
em.find(Obj.class,id)

works as I want it to.

It also works when I define another function within the same EJB to get objects, I've marked it with @TransactionAttribute(SUPPORTS), but I am not sure whether this is necessary. It works for me.
Re: Adding/removing relations [message #1090044 is a reply to message #1089966] Mon, 19 August 2013 16:30 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris Delahunt
Messages: 1034
Registered: July 2009
Senior Member
Using a different EntityManager instances results in different Entity instances being returned for the same entity ID value. In this case, the editingObj = em.find(Obj.class, objId); is using a different EntityManager from the one injected into the a() method call, so the editingObj instances will be different - the first one is not managed in or by the new EntityManager context. This allows transactional isolation so that when the second one's transaction commits, only changes made in that context are picked up.

This means that the transaction settings also affect your EntityManager injection. If your inner method supports transactions, it can use the same EntityManager instance as the caller method. If the transactional settings are different, then it usually must use a different EntityManager context so that changes do not get mixed into the different transactions. It might not be a good idea to cache entities within session beans, and instead look them up as needed from the current EntityManager context. EclipseLink has a second level cache which can be used to avoid database hits anyway.

Best Regards,
Chris
Re: Adding/removing relations [message #1090639 is a reply to message #1090044] Tue, 20 August 2013 12:37 Go to previous message
Neikius Mising name is currently offline Neikius Mising name
Messages: 43
Registered: April 2011
Member
Yea I remember reading about this a while ago but then I just discarded it since it was not important then... it definitely is now. Thanks!

The thing is I like how extended persistence context works in my case: I want to stack changes from several methods and apply them when user clicks save. There is a slight problem of multiple users editing the same object and locks don't seem to solve it at all, so I will probably just implement locking at the application level (maybe some idea why locking em.lock() doesn't work? I've tried all possible lock types and it will still allow another user to lock the same object again... I guess it could be another EM instance problem as it is here).

Problem with transactions here is that my methods don't support transactions. From what I've read of EJB transactions other method can merge existing transaction (that is what you were talking about), but can I make this work in my case? Maybe NOT_SUPPORTED is unnecessary? I still want all the user's changes to be applied only when I call em.flush() and not before. I am a bit far into this though, so I guess fetching a few objects won't hurt right now... but I don't have the luxury of time to learn and experiment anymore.

Oh and regarding caching entities in session beans, I am only holding onto two objects: the item user is editing and user object itself since I have to link them too. Problem is objects are quite deeply linked in the schema and there are a ton of relations. This shouldn't be too much or is it? The other way of doing things was to merge a detached object from jsf session when editing is complete, but I had huge problems with relations propagating weirdly and even bigger problems when checking for existing relations. At least all that is solvable now as it is I think. I am quite sure concurrent editing will be very rare.

Thanks again though, I will post more if I manage to find out something new regarding this.
Previous Topic:Need advice on setup Phone ManyToOne JoinColumns Employee Relationship
Next Topic:Native Eclipselink versus JPA Eclipselink defaults
Goto Forum:
  


Current Time: Thu Oct 23 21:26:30 GMT 2014

Powered by FUDForum. Page generated in 0.12154 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software