[cl-prevalence-devel] restore operation fails with linked objects
Nico de Jager
ndj at hivsa.com
Thu Mar 13 09:08:08 UTC 2008
Evan Monroig <evan.monroig at gmail.com> writes:
> Hi,
>
> I found a bug in cl-prevalence, where the objects that are linked are
> not properly reconstructed from the transaction log (restoring from a
> snapshot is fine).
>
> I included minimal example code in the attached file and also on lisp
> paste [1] for easy reference.
>
> Joe and Ma Dalton are two persons, and the slot 'PARENT of Joe is Ma.
> When the objects are reconstructed from the transaction log, three
> objects are created: Joe, Ma and another Ma that is the value of the
> slot 'PARENT of Joe, but not the same object as the first Ma.
>
> A look at the transaction-log.xml file shows that in the transaction for
> the creation of Joe, Ma is referred to as a person and the values of its
> slots are indicated, instead of referring to the previously created
> instance.
>
> Can anyone reproduce this? Any ideas to fix? I guess that the
> serialization doesn't know of the already existing objects.
>
> I'm working on SBCL 1.0.6 on Ubuntu 07.10 and cl-prevalence is the last
> released version.
>
> Thanks in advance,
>
> Evan
>
> [1] http://paste.lisp.org/display/57271
Hi
I can duplicate your reported behaviour in LispWorks Pro 5.0.2 for Linux, but I thought this was normal behaviour. When passing a compound object as parameter to a data manipulation/creation transaction function, information is saved in the transaction log to recreate such an object. I suppose code can be added to check for OBJECT-WITH-ID descendants when the transaction log is replayed to just return the same (under EQ) object (instead of reconstructing it) if such an object already exists, but in the general case (i.e. non OBJECT-WITH-ID objects) there is no way to check for this type of equality and you'll end up with duplicates. Anyone please correct me if I am wrong.
So,
1) you'll either have to save Ma's ID in Joe's parent slot when using managed prevalence, or
2) don't use managed prevalence and write your own transaction functions, or wrap the managed prevalence transactions as helper-only functions in your own transactions. In this case you still pass Ma's ID to the transaction (and only Ma's ID is stored in the transaction log during the recording of the transaction in contrast to the all the info to reconstruct Ma's object). Then, inside the transaction, you can fetch Ma's object yourself and this way assign the Ma object to Joe's parent slot. I usually follow this approach. In general I don't pass compound objects to transactions, but pass IDs or the slots as parameters to construct the object inside the transaction. It's a bit tedious, though, and I am sure it can be automated with a more hefty managed prevalence implementation.
HTH.
Nico
More information about the Cl-prevalence-devel
mailing list