Quantcast

TopLink to EclipseLink migration

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

TopLink to EclipseLink migration

Sterba
This post has NOT been accepted by the mailing list yet.
This post was updated on .
Different behavior for new objects in nested UnitOfWork
We are migrating about a dozen applications from TopLink to EclipseLink. The package renamer helps a lot, but we have experienced a different behavior in fallowing situation:

In One-To-Many relationships (e.g. Person-To-PhoneNumber ) we are manipulating the PhoneNumbers side via nested UnitOfWork acquired from Persons UnitOfWork. Updating already persisted PhoneNumbers works fine. But when we create a new PhoneNumber (via one nested UOW, and commit it to the parent UOW), and then if user decide to change this newly created PhoneNumber in the same transaction (we will create another nested UOW, edit the fields, and commit it to the parent UOW), the change will not propagate to the parent. In TopLink it will. This situation happens only when daling with new objects.

Person is mapped to PhoneNumber as One-To-Many, and PhoneNumber si mapped to Person as One-To-One.

Is there a different behavior in working with new objects in EclipseLink than in TopLink? Or is it because one-to-many situation?

Any suggestions are appreciated (this kind of pattern is used many times in our applications).  

I hope this example pseudocode will explain more:

public class TestExample {

        public void runTest(Session session) {
                //step1 - User tries to edit persisted Person object
                Person person = (Person) session.readObject(Person.class);
                UnitOfWork uow = session.acquireUnitOfWork();
                Person personClone = (Person) uow.registerObject(person);

                //step2 - User adds new PhoneNumber to person
                addPhoneNumber(personClone, uow);

                //step3 - User edits newly creted PhoneNumber
                PhoneNumber phoneNumber = personClone.getPhoneNumbers().get(0);
                UnitOfWork nestedUow = uow.acquireUnitOfWork();
                PhoneNumber phoneNumberClone = (PhoneNumber) nestedUow.registerObject(phoneNumber);
                phoneNumberClone.setValue(2000);
                nestedUow.commit();

                //step4 - compare difference idn TopLink and EcliseLink
                //in TopLink the value will be 2000
                //in EclipseLink the value will be still 1000
                int value = personClone.getPhoneNumbers().get(0).getValue();
        }

        private void addPhoneNumber(Person personClone, UnitOfWork parentUow) {
                UnitOfWork nestedUowInsert = parentUow.acquireUnitOfWork();
                Person personCloneInsert = (Person) nestedUowInsert.registerObject(personClone);
                PhoneNumber phoneNumber = new PhoneNumber();
                phoneNumber.setPerson(personCloneInsert);
                phoneNumber.setValue(1000);
                phoneNumber.getPerson().getPhoneNumbers().add(0, phoneNumber);
                nestedUowInsert.commit();
        }

}

class Person {

        private final ValueHolderInterface phoneNumbers = new ValueHolder();

        public Vector<PhoneNumber> getPhoneNumbers() {
                if (this.phoneNumbers.getValue() == null)
                        this.phoneNumbers.setValue(new Vector<PhoneNumber>());
                return (Vector<PhoneNumber>) phoneNumbers.getValue();
        }

}

class PhoneNumber {

        private final ValueHolderInterface person = new ValueHolder();
        private int value;

        public void setPerson(Person person) {
                this.person.setValue(person);
        }

        public Person getPerson() {
                return (Person) person.getValue();
        }

        public int getValue() {
                return value;
        }

        public void setValue(int value) {
                this.value = value;
        }
}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TopLink to EclipseLink migration

jamesssss
It could be a bug.  Try to isolate a test case and log a bug.

You might be able to change your usage of the nested unit of works to avoid the issue.  Try getting the changes for the nested unit of work before commit and see if it has detected the change.  It could be an issue with merging not being able to match the new object.  Ensure the new object's id has been assigned.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TopLink to EclipseLink migration

Sterba
This post has NOT been accepted by the mailing list yet.
Thanks for the pointers Jamesssss,
I think you are right with your suggestions. If I assign an id to the new object (when creating in nested UOW), then it works as expected. Anyway it could be still a bug.

I did not do that in the example, because I tried to simulate the design of these old projects we are migrating. And those projects are expecting to have id == null until commit.

I did not find anything weird in changeSets before commit, but I might be not looking for the right thing. Fiddling with different ways how to register object in nested UOW did not helped me either (when registering persisted PhoneNumber as nestedUow.registerExistingObject and new PhoneNumber as nestedUow.registerNewObject results in loss of reference to Person in persisted record. Weird)

I have created small test project to reproduce this bug on DerbyDB, both for EclipseLink and TopLink. It can be downloaded here

Should I log a bug or what should I try next? Cheers
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TopLink to EclipseLink migration

Sterba
This post has NOT been accepted by the mailing list yet.
In reply to this post by jamesssss
I have tried few versions of TopLink I have hands on. It worked on 9.0.3 and 9.0.4.8 but not on 10.1.3.0 and 10.1.3.3

It did worked on all versions (including EclipseLink) when I set an id !=null while creating new object. But those old applications I`m migrating are expecting to have id == null until commit.
Loading...