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 <[email protected]> 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 <[email protected]> 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;
}
// }}
}