You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@isis.apache.org by Robert Matthews <rm...@nakedobjects.org> on 2012/07/06 20:54:17 UTC

Re: Persisting a object an aggregated component fails.

Dan

Just starting to look at this.  With a simple case it works (with the 
in-memory store), well it does with calls in one order but not another. 
That is:-

         Contact c = newTransientInstance(Contact.class);
         c.setName("Fred");
         c.addPhoneNumber().setNumber("0700123456");
         persist(c);

doesn't work, but the following does not:-

         Contact c = newTransientInstance(Contact.class);
         c.setName("Fred");
         persist(c);
         c.addPhoneNumber().setNumber("0700123456");

Its failing in the open() method in InMemoryObjectStore.  The question 
on my mind at the moment is whether this store should work with 
aggregates (my mind's a blank).  I'm sure the XML one has not been 
updated yet, but I can't recall about the in-memory one.

Regards

Rob


On 26/06/12 23:14, Dan Haywood wrote:
> Hi Rob,
> I've raised ticket ISIS-234, written a test to reproduce your example, and
> checked in a change (along the lines I suggested) that fixes those tests.
>
> So, I've marked ISIS-234 as resolved, pending further testing by you,
> if you'd be so kind?!
>
> Do also have a read of the comment that I added to ISIS-234 ticket
> though... it may be that this initial attempt at fixing this bug may not be
> sufficient.
>
> Cheers
> Dan
>
> On 24 June 2012 15:33, Dan Haywood <da...@haywood-associates.co.uk> wrote:
>
>> Hi Rob,
>> thanks for doing this testing.  My initial thought is that the framework
>> will need to keep track of the before/after OIDs, in some sort of hash.
>>   Not sure, exactly, how the change in implementation caused the breakage,
>> other than to say that a lot of stuff did change and so it doesn't surprise
>> me overly.
>>
>> Thanks for putting together a simple test case; I'll use it as the basis
>> for developing some sort of fix, this week, I hope.
>>
>> Dan
>>
>>
>> On 22 June 2012 01:22, Robert Matthews <rm...@nakedobjects.org> wrote:
>>
>>> Hi Dan
>>>
>>> I've been testing out the aggregated types and have found that the latest
>>> code no longer works.  I've had a look through but cannot see where the
>>> problem is being seeded.   I have a snippet of code that shows the problem:
>>> basically a Contact object has a collection of phone number objects where
>>> the phone number class is  marked as @Aggregated.  Creating a new instance
>>> of the contact with a phone number and then persisting it gives the
>>> following trace.
>>>
>>> java.lang.NullPointerException
>>>     at org.apache.isis.runtimes.dflt.**runtime.persistence.**
>>> adapterfactory.pojo.**PojoAdapter.getResolveState(**PojoAdapter.java:130)
>>>     at org.apache.isis.runtimes.dflt.**runtime.persistence.**
>>> objectstore.algorithm.**PersistAlgorithmAbstract.**objectIsStandalone(**
>>> PersistAlgorithmAbstract.java:**89)
>>>     at org.apache.isis.runtimes.dflt.**runtime.persistence.**
>>> objectstore.algorithm.**PersistAlgorithmAbstract.**
>>> alreadyPersistedOrNotPersistab**leOrServiceOrStandalone(**
>>> PersistAlgorithmAbstract.java:**64)
>>>     at org.apache.isis.runtimes.dflt.**runtime.persistence.**
>>> objectstore.algorithm.dflt.**DefaultPersistAlgorithm.**persist(**
>>> DefaultPersistAlgorithm.java:**70)
>>>     at org.apache.isis.runtimes.dflt.**runtime.persistence.**
>>> objectstore.algorithm.dflt.**DefaultPersistAlgorithm.**makePersistent(**
>>> DefaultPersistAlgorithm.java:**61)
>>>     at org.apache.isis.runtimes.dflt.**runtime.persistence.**
>>> objectstore.algorithm.dflt.**DefaultPersistAlgorithm.**persist(**
>>> DefaultPersistAlgorithm.java:**93)
>>>     at org.apache.isis.runtimes.dflt.**runtime.persistence.**
>>> objectstore.algorithm.dflt.**DefaultPersistAlgorithm.**makePersistent(**
>>> DefaultPersistAlgorithm.java:**65)
>>>     at org.apache.isis.runtimes.dflt.**runtime.system.persistence.**
>>> PersistenceSession$4.execute(**PersistenceSession.java:1041)
>>>     at org.apache.isis.runtimes.dflt.**runtime.system.transaction.**
>>> IsisTransactionManager.**executeWithinTransaction(**
>>> IsisTransactionManager.java:**151)
>>>     at org.apache.isis.runtimes.dflt.**runtime.system.persistence.**
>>> PersistenceSession.**makePersistentInPersistenceLay**
>>> er(PersistenceSession.java:**1033)
>>>     at org.apache.isis.runtimes.dflt.**runtime.system.persistence.**
>>> PersistenceSession.**makePersistent(**PersistenceSession.java:1029)
>>>     at org.apache.isis.runtimes.dflt.**runtime.persistence.internal.**
>>> RuntimeContextFromSession$5.**makePersistent(**RuntimeContextFromSession.
>>> **java:138)
>>>     at org.apache.isis.core.**metamodel.services.container.**
>>> DomainObjectContainerDefault.**persist(**DomainObjectContainerDefault.**
>>> java:242)
>>>     at org.apache.isis.applib.**AbstractContainedObject.**persist(**
>>> AbstractContainedObject.java:**240)
>>>     at fixture.example.todo.**ToDoItemsFixture.install(**
>>> ToDoItemsFixture.java:39)
>>>     at org.apache.isis.runtimes.dflt.**runtime.fixtures.**
>>> FixturesInstallerDelegate.**installFixture(**FixturesInstallerDelegate.**
>>> java:212)
>>>
>>> (Setting the field with the aggregate after the contact is persisted
>>> works though. And, storing the phone number as just a reference rather than
>>> adding it to a collection also works.)
>>>
>>> Looking at the state of things when this error occurs the problem happens
>>> as the parent oid of the aggregate oid is the old, pre-persisted, oid and
>>> the object loader only has the new, now-persisted oid in its map so can't
>>> find the contact and hence returns null. What has changed since 0.3.0
>>> (which works) to cause this to now fail?
>>>
>>> The test code is included below.
>>>
>>> Regards
>>>
>>> Rob
>>>
>>>
>>>
>>> public class TestFixture extends AbstractFixture {
>>>
>>>     @Override
>>>     public void install() {
>>>         Contact c = newTransientInstance(Contact.**class);
>>>         c.setName("Fred");
>>>         c.addPhoneNumber().setNumber("**0700123456");
>>>         persist(c);
>>>     }
>>> }
>>>
>>> public class Contact extends AbstractDomainObject {
>>>
>>>     // {{ Name
>>>     private String name;
>>>
>>>     @MemberOrder(sequence = "1")
>>>     public String getName() {
>>>         return name;
>>>     }
>>>
>>>     public void setName(final String name) {
>>>         this.name = name;
>>>     }
>>>     // }}
>>>
>>>     // {{ PhoneNumbers
>>>     private List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>();
>>>
>>>     @MemberOrder(sequence = "2.2")
>>>     public List<PhoneNumber> getPhoneNumbers() {
>>>         return phoneNumbers;
>>>     }
>>>
>>>     public void setPhoneNumbers(final List<PhoneNumber> phoneNumbers) {
>>>         this.phoneNumbers = phoneNumbers;
>>>     }
>>>     // }}
>>>
>>>     // {{ addPhoneNumber
>>>     @MemberOrder(sequence = "1.1")
>>>     public PhoneNumber addPhoneNumber() {
>>>         PhoneNumber phoneNumber = newAggregatedInstance(**
>>> PhoneNumber.class);
>>>         getPhoneNumbers().add(**phoneNumber);
>>>         return phoneNumber;
>>>     }
>>> }
>>>
>>> @Aggregated
>>> public class PhoneNumber {
>>>
>>>     // {{ Number
>>>     private String number;
>>>
>>>     @MemberOrder(sequence = "1.1")
>>>     public String getNumber() {
>>>         return number;
>>>     }
>>>
>>>     public void setNumber(final String number) {
>>>         this.number = number;
>>>     }
>>>     // }}
>>> }
>>>
>>>