I
have a problem popping up in production much more often than I'd like.
Unfortunately, I cannot reproduce it in any of our test environments.
Users told me what they are doing, and I tried the same dozens and
hundreds of times, but I don't understand what is going on.
When users commit a Transaction after some operation, they sometimes get an "Inconsistent
values in field" error. Sometimes they also get a "Conflicting Values
in Rows", which seems to be somewhat the same thing...?).
A few things are strange here. But let's first look at a part of the walkback:
DirectMapping>>#mapFromObject:toTarget:puttingRowsIn:
receiver = a DirectMapping(id)
arg1 = a Konto (1572965): 1791 Umsatzsteuer frühere Jahre
arg2 = a Konto (1572965): 1791 Umsatzsteuer frühere Jahre
arg3 = a RowMapForMementos
temp1 = 1572965
temp2 = 1572965
temp3 = a DatabaseRow(KPELEMENT)
Field(KPELEMENT.id)->1572848
Field(KPELEMENT.version)->an Object
Field(KPELEMENT.typ)->'KO'
Field(KPELEMENT.bezeichnung)->an Object
Field(KPELEMENT.kontonummer)->an Object
Field(KPELEMENT.anfangssaldo)->an Object
Field(KPELEMENT.abschlusssaldo)->an Object
Field(KPELEMENT.euerKz)->an Object
Field(KPELEMENT.cont_id)->an Object
Field(KPELEMENT.rahmen_element_id)->an Object
Field(KPELEMENT.wurzel_id)->an Object
Field(KPELEMENT.metakonto_nr)->an Object
Field(KPELEMENT.kto_orig_id)->an Object
So first thing here is: it seems most contents of the Row are "an Object" which definitely is rubbish.
But
reading the code of this method and looking at the temps and args, I
have at least some idea of what might be going wrong here. This is the
method:
mapFromObject: anObject toTarget: target puttingRowsIn: aRowMap
| dbValue value row |
self canWrite ifFalse: [^self].
value := self getValueFrom: anObject.
value := self session realObjectFor: value ifNone: [^self].
dbValue := self convertedDbValueOf: value.
row := aRowMap findOrAddRowForTable: self field table withKey: target.
row at: field put: dbValue
What
I find interesting is that the row which is displayed here is not the
one that the meapper was looking for. The row to be changed has the id 157296, but the row in the Walkback has the id Field(KPELEMENT.id)->157284. So I guess the problem is that #findOrAddRowForTable: self field table withKey: target. returns the wrong row...
There is no point in changing the contents of ID anyways, since it is the primary key of the row....
So what would a Glorp pro do to "debug" this deeper - especially given that we have no way to reproduce this problem (yet)?
Joachim