Hi Ellen,
No, it should work by just calling merge() on the detached instance,
providing that you have cascade flags set on the relationships correctly.
Also, I'm surprised your code below doesn't throw a unique constraint
exception if you are adding new instances to the managed study.
What types of cascade flags do you use?
thanks,
-marina
Ellen Kraffmiller wrote:
> Hi,
> After doing some testing, I've found a way to update the dependent
> collection from the detached study that works:
>
> public void updateStudy(Study detachedStudy){
> Study managedStudy = em.find(Study.class,detachedStudy.getId());
>
> // Remove existing collections on managed study
> for (Iterator<FileCategory> it =
> managedStudy.getFileCategories().iterator(); it.hasNext();) {
> FileCategory elem = it.next();
> em.remove(elem);
> }
> managedStudy.getFileCategories().clear();
>
> // Add the collection from the detached study
> //(need to create new FileCategory objects, if we don't we get a
> "trying to persist a detched object" exception)
>
> for (Iterator<FileCategory> it =
> detachedStudy.getFileCategories().iterator(); it.hasNext();) {
> FileCategory elem = it.next();
> FileCategory fileCategory = new FileCategory();
> fileCategory.setOtherId(elem.getOtherId());
> fileCategory.setAgency(elem.getAgency());
> fileCategory.setStudy(managedStudy);
> managedStudy.getFileCategories().add(fileCategory);
> }
>
> This seems like an awful lot of code to do a relatively straightforward
> update. Is this the recommended approach?
> The only way I see to avoid this is to us Stateful Session bean with an
> extended persistence context. Is that how most people handle this?
> Thanks,
> Ellen
>
>
> gdurand_at_hmdc.harvard.edu wrote:
>
>>
>> We are prefetching relationships. We prefer to do it that way because
>> sometimes we don't need to get them.
>>
>>
>> Quoting Marina Vatkina <Marina.Vatkina_at_Sun.COM>:
>>
>>> Ellen,
>>>
>>> Are you adding a file category to a study before passing it back?
>>> Is 'fileCategories' marked as FetchType.EAGER when you pass a
>>> study to the client (ToMany relationship defaults to LAZY fetching),
>>> or do you prefetch the relationships? If not, does it make a difference
>>> if you do?
>>>
>>> thanks,
>>> -marina
>>>
>>> Ellen Kraffmiller wrote:
>>>
>>>> Thanks Marina, please see my comments
>>>> -Ellen
>>>>
>>>> Marina Vatkina wrote:
>>>>
>>>>> Ellen,
>>>>>
>>>>> Ellen Kraffmiller wrote:
>>>>>
>>>>>> Hi Gordon & Marina,
>>>>>> After doing more testing, the problem seems to be related to
>>>>>> using a detached entity. In our original example, the study
>>>>>> object we are merging was previously detached and sent to the web
>>>>>> tier. I tried the same logic with a Study entity that is
>>>>>> managed, and it works.
>>>>>>
>>>>>> So, to summarize, this works:
>>>>>> doUpdate(Long id) {
>>>>>> Study study = em.find(Study.class, id);
>>>>>> FileCategory c = new FileCategory();
>>>>>> c.setName( "test" );
>>>>>> c.setStudy(study);
>>>>>> study.getFileCategories().add(c);
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> You do not need to merge a managed instance, assuming you have cascade
>>>>> PERSIST or ALL set:
>>>>>
>>>>>> em.merge(study);
>>>>>
>>>>>
>>>>>
>>>>>
>>>> Right, I forgot about that when I was doing the test.
>>>>
>>>>>>
>>>>>> }
>>>>>>
>>>>>> But the following throws an Opimistic Lock Exception:
>>>>>> (No modifications to the fileCategories collection were made
>>>>>> while the study was detached.)
>>>>>>
>>>>>> doUpdate(Study detachedStudy) {
>>>>>> FileCategory c = new FileCategory();
>>>>>> c.setName( "test" );
>>>>>> c.setStudy(study);
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Do you mean 'detachedStudy'?
>>>>
>>>>
>>>>
>>>>
>>>> Yes, that was a typo.
>>>>
>>>>>
>>>>>> study.getFileCategories().add(c);
>>>>>> em.merge(study);
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Does the opposite works (with appropriate cascade settings)?
>>>>>
>>>>> em.merge(study);
>>>>>
>>>>> FileCategory c = new FileCategory();
>>>>> c.setName( "test" );
>>>>> c.setStudy(study);
>>>>> study.getFileCategories().add(c);
>>>>>
>>>>>
>>>> This may work, but it doesn't really fit our requirements. Our
>>>> example is simplified to show what is happening in one code
>>>> snippet. Just to give you a background on what we are doing, we are
>>>> implementing a standard web application with forms for updating a
>>>> Study and all its related data. So, in this case, we are getting a
>>>> Study entitiy from the database, presenting a form to the user
>>>> where he can update the file categories for the Study (as well as
>>>> other dependent entities), then calling a session bean method that
>>>> attempts to merge the Study to the database. We can't add the
>>>> fileCategory object after merging the study, because the study
>>>> being passed to the session bean already has all the file category
>>>> data (and other dependent collections) set.
>>>>
>>>>>
>>>>> thanks,
>>>>> -marina
>>>>>
>>>>>> }
>>>>>>
>>>>>> Is something we need to be doing differently to merge the detached
>>>>>> study?
>>>>>>
>>>>>> Thanks,
>>>>>> Ellen
>>>>>>
>>>>>> Marina Vatkina wrote:
>>>>>>
>>>>>>> Gordon,
>>>>>>>
>>>>>>> Is there a way to check which exactly PK causes this error?
>>>>>>> Can it be that there is another FileCategory instance that
>>>>>>> is the problem?
>>>>>>>
>>>>>>> thanks,
>>>>>>> -marina
>>>>>>>
>>>>>>> Gordon Yorke wrote:
>>>>>>>
>>>>>>>> Nothing jumps out as an issue, if you are not on the latest
>>>>>>>> version of TopLink Essentials I would recommend updating your
>>>>>>>> TopLink Essentials jar and if the problem persists file a
>>>>>>>> glassfish issue with testcase.
>>>>>>>> --Gordon
>>>>>>>>
>>>>>>>> -----Original Message-----
>>>>>>>> From: Ellen Kraffmiller [mailto:ekraffmiller_at_hmdc.harvard.edu]
>>>>>>>> Sent: Thursday, September 28, 2006 11:24 AM
>>>>>>>> To: persistence_at_glassfish.dev.java.net
>>>>>>>> Subject: Re: Trting to add new child entity; getting
>>>>>>>> OptimisticLockException
>>>>>>>>
>>>>>>>>
>>>>>>>> The version is being left as null - we are never setting it.
>>>>>>>> Thanks,
>>>>>>>> Ellen
>>>>>>>>
>>>>>>>> Gordon Yorke wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>> Hello Ellen,
>>>>>>>>> In the constrctor of FileCategory is version being initialized
>>>>>>>>> to new Long(X) or being left as null?
>>>>>>>>> --Gordon
>>>>>>>>>
>>>>>>>>> -----Original Message-----
>>>>>>>>> From: Ellen Kraffmiller [mailto:ekraffmiller_at_hmdc.harvard.edu]
>>>>>>>>> Sent: Thursday, September 28, 2006 10:27 AM
>>>>>>>>> To: persistence_at_glassfish.dev.java.net
>>>>>>>>> Subject: Re: Trting to add new child entity; getting
>>>>>>>>> OptimisticLockException
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Hi Gordon,
>>>>>>>>> I am working with Gustavo on this problem so I thought I'd
>>>>>>>>> answer your
>>>>>>>>> questions. The version field is defined as:
>>>>>>>>>
>>>>>>>>> @Version
>>>>>>>>> private Long version;
>>>>>>>>> (with normal getters and setters)
>>>>>>>>>
>>>>>>>>> We are using SostgreSQL, and the database column is version, int8.
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Ellen
>>>>>>>>>
>>>>>>>>> Gordon Yorke wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>> Hello Gustavo,
>>>>>>>>>> What is the version field in FileCategory being initialized
>>>>>>>>>> to? What type is the version field?
>>>>>>>>>> --Gordon
>>>>>>>>>>
>>>>>>>>>> -----Original Message-----
>>>>>>>>>> From: gdurand_at_hmdc.harvard.edu [mailto:gdurand_at_hmdc.harvard.edu]
>>>>>>>>>> Sent: Wednesday, September 27, 2006 5:57 PM
>>>>>>>>>> To: persistence_at_glassfish.dev.java.net
>>>>>>>>>> Subject: Trting to add new child entity; getting
>>>>>>>>>> OptimisticLockException
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> I'm am trying a very simple example and am getting a problem
>>>>>>>>>> (I am using glassfish v2 milestone 1):
>>>>>>>>>>
>>>>>>>>>> Our DB has a Study entity which has a one to many relationship
>>>>>>>>>> with a FileCategory entity.
>>>>>>>>>>
>>>>>>>>>> When I try to add a FileCategory to an existing study:
>>>>>>>>>>
>>>>>>>>>> Collection categories = study.getFileCategories();
>>>>>>>>>>
>>>>>>>>>> FileCategory c = new FileCategory();
>>>>>>>>>> c.setName( "test" );
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> c.setStudy(study);
>>>>>>>>>> categories.add(c);
>>>>>>>>>>
>>>>>>>>>> em.merge(study);
>>>>>>>>>>
>>>>>>>>>> I am getting:
>>>>>>>>>>
>>>>>>>>>> Exception Details:
>>>>>>>>>> oracle.toplink.essentials.exceptions.OptimisticLockException
>>>>>>>>>> Exception Description: The object
>>>>>>>>>> [edu.harvard.hmdc.vdcnet.study.FileCategory_at_1f1c748] cannot be
>>>>>>>>>> merged
>>>>>>>>>> because it has changed or been deleted since it was last read.
>>>>>>>>>> {3}Class> edu.harvard.hmdc.vdcnet.study.FileCategory
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Any ideas why this is happening, since the FileCategory
>>>>>>>>>> doesn't exist
>>>>>>>>>> in the first place? (I have seen an example in the O'Reilly
>>>>>>>>>> book that
>>>>>>>>>> pretty much does just this)?
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Gustavo
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>
>>>>>
>>
>>
>>