Forcing save when #register: doesn't work

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Forcing save when #register: doesn't work

Esteban A. Maringolo
Hi,

I have a weird situation where I can't find an easy way to debug (as usual).

Within a unit of work I read some object A from the DB, explicitly
#register: it in the session, modify some of its attributes, and then
commit the unit of work and the changes are not saved to the table.

Following the #register: message sends it ends up being registered as
an existing object (which is true), but I don't understand why the
changes are not applied afterwards since there are changes between the
read object (and hence its rowmap) and the new one.

Is there an easy way to debug this? This happens somehow deep in a ETL
and I can't find a way to reproduce it outside of the actual execution
of the ETL, so I want to identify the issue and then write the unit
test once the fix is done.

Thanks!

Esteban A. Maringolo

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/glorp-group/CAJMgPCJ8%3DuUWYFVH%3DaKVyCSqYd_wCmBVH4g2u0RNDaq63CgJrQ%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Forcing save when #register: doesn't work

Alan Knight
There is a debugRead/debugWrite type of variable on mappings that you can set, and you will get a halt when it reads or writes. That's probably the most useful hidden trick. But that will show you when it's being written to the RowMap. Do you know that the RowMaps are different? I guess you could halt/log on the various steps. Is the object different from the registered copy. Does the mapping write the new value into the generated RowMap. Is the generated RowMap for the new version of this object different from the old one? Does the differencing produce a RowMap that contains the modified value? Does that modified value get written from the RowMap to the DB? RowMaps are not trivial to inspect, but should have all the information.

I'm a little bit suspicious of the explicit register, though it ought to be harmless. When you read within a unit of work things are automatically registered.

And actually thinking of the last couple of steps I wrote up there, is this a funny VA-specific object, where registration/lookup of the original object might not be working? Registration has to have special cases for the different ways that collections are implemented in different dialects. There could be others. Although if that was the reason I'd expect it to be easy to reproduce in isolation.


On Sun, Nov 1, 2020 at 8:20 PM Esteban Maringolo <[hidden email]> wrote:
Hi,

I have a weird situation where I can't find an easy way to debug (as usual).

Within a unit of work I read some object A from the DB, explicitly
#register: it in the session, modify some of its attributes, and then
commit the unit of work and the changes are not saved to the table.

Following the #register: message sends it ends up being registered as
an existing object (which is true), but I don't understand why the
changes are not applied afterwards since there are changes between the
read object (and hence its rowmap) and the new one.

Is there an easy way to debug this? This happens somehow deep in a ETL
and I can't find a way to reproduce it outside of the actual execution
of the ETL, so I want to identify the issue and then write the unit
test once the fix is done.

Thanks!

Esteban A. Maringolo

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/glorp-group/CAJMgPCJ8%3DuUWYFVH%3DaKVyCSqYd_wCmBVH4g2u0RNDaq63CgJrQ%40mail.gmail.com.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/glorp-group/CAGWHZ987bPV7LjAGm4XVe8equH-xT3toAJhmjrdP3Y25%3Dk_GOw%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Forcing save when #register: doesn't work

Esteban A. Maringolo
Hi Alan,

Thanks for responding, I'm currently doing #forceSaveOf: and it is working.

forceSaveOf: anObject
"This is the same as registering an object, but it tells us to disregard whether/how the object has changed and to save all of its fields. This is useful if we need to register an object after changes have occurred, and can be used to implement something more like an object by object save facility. Still somewhat experimental."
  | realObject |
  realObject := self realObjectFor: anObject ifNone: [^self].
  self inUnitOfWorkDo: [currentUnitOfWork registerAsNew: realObject]

What I don't understand is why registering it as new still generates an UPDATE instead of an INSERT.

I know that objects read from the database are automatically registered, but since I do a lot of "read and if it doesn't exist then create it", and I treat both cases the same, so I do something like:

myPlayer := self readPlayerWithId: id ifNone: [self createNewPlayerWithId: id].
db register: myPlayer.

It is a simplified version of the code, but more or less it does the same for several objects that are sync'ed from an API.


Regards!

Esteban A. Maringolo


On Thu, Nov 5, 2020 at 10:55 AM Alan Knight <[hidden email]> wrote:
There is a debugRead/debugWrite type of variable on mappings that you can set, and you will get a halt when it reads or writes. That's probably the most useful hidden trick. But that will show you when it's being written to the RowMap. Do you know that the RowMaps are different? I guess you could halt/log on the various steps. Is the object different from the registered copy. Does the mapping write the new value into the generated RowMap. Is the generated RowMap for the new version of this object different from the old one? Does the differencing produce a RowMap that contains the modified value? Does that modified value get written from the RowMap to the DB? RowMaps are not trivial to inspect, but should have all the information.

I'm a little bit suspicious of the explicit register, though it ought to be harmless. When you read within a unit of work things are automatically registered.

And actually thinking of the last couple of steps I wrote up there, is this a funny VA-specific object, where registration/lookup of the original object might not be working? Registration has to have special cases for the different ways that collections are implemented in different dialects. There could be others. Although if that was the reason I'd expect it to be easy to reproduce in isolation.


On Sun, Nov 1, 2020 at 8:20 PM Esteban Maringolo <[hidden email]> wrote:
Hi,

I have a weird situation where I can't find an easy way to debug (as usual).

Within a unit of work I read some object A from the DB, explicitly
#register: it in the session, modify some of its attributes, and then
commit the unit of work and the changes are not saved to the table.

Following the #register: message sends it ends up being registered as
an existing object (which is true), but I don't understand why the
changes are not applied afterwards since there are changes between the
read object (and hence its rowmap) and the new one.

Is there an easy way to debug this? This happens somehow deep in a ETL
and I can't find a way to reproduce it outside of the actual execution
of the ETL, so I want to identify the issue and then write the unit
test once the fix is done.

Thanks!

Esteban A. Maringolo

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/glorp-group/CAJMgPCJ8%3DuUWYFVH%3DaKVyCSqYd_wCmBVH4g2u0RNDaq63CgJrQ%40mail.gmail.com.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/glorp-group/CAGWHZ987bPV7LjAGm4XVe8equH-xT3toAJhmjrdP3Y25%3Dk_GOw%40mail.gmail.com.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/glorp-group/CAJMgPCLyJpFpOyh%3D32HdHRNxExzoDS1x-iNUjP53w%2BFZ7wxfpw%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Forcing save when #register: doesn't work

jtuchel
Esteban,

I am not sure I understand this line of code:

self inUnitOfWorkDo: [currentUnitOfWork registerAsNew: realObject]

doesn't currentUnitOfWork refernence the currentUnitOfWork of this context? And when you put it in the inUnitOfWorkDo: Block, that other unitOfWork is going to be the active unitOfWork, but not the one you thing it is? A stupid explanation, I know, let's try with a code example: I think your code is equivalent to this:

a:= self currentUnitOfWork.
self inUnitOfWorkDo: [a registerAsNew: realObject].

Or am I wrong? I would guess that the result looks different if you change your code to:

self inUnitOfWorkDo: [self privateGetCurrentUnitOfWork registerAsNew: realObject].


I've had a long day of debugging and not understanding a lot of what I observe, so please bear with me if this is total nonsense...

Joachim


[hidden email] schrieb am Montag, 9. November 2020 um 02:11:07 UTC+1:
Hi Alan,

Thanks for responding, I'm currently doing #forceSaveOf: and it is working.

forceSaveOf: anObject
"This is the same as registering an object, but it tells us to disregard whether/how the object has changed and to save all of its fields. This is useful if we need to register an object after changes have occurred, and can be used to implement something more like an object by object save facility. Still somewhat experimental."
  | realObject |
  realObject := self realObjectFor: anObject ifNone: [^self].
  self inUnitOfWorkDo: [currentUnitOfWork registerAsNew: realObject]

What I don't understand is why registering it as new still generates an UPDATE instead of an INSERT.

I know that objects read from the database are automatically registered, but since I do a lot of "read and if it doesn't exist then create it", and I treat both cases the same, so I do something like:

myPlayer := self readPlayerWithId: id ifNone: [self createNewPlayerWithId: id].
db register: myPlayer.

It is a simplified version of the code, but more or less it does the same for several objects that are sync'ed from an API.


Regards!

Esteban A. Maringolo


On Thu, Nov 5, 2020 at 10:55 AM Alan Knight <[hidden email]> wrote:
There is a debugRead/debugWrite type of variable on mappings that you can set, and you will get a halt when it reads or writes. That's probably the most useful hidden trick. But that will show you when it's being written to the RowMap. Do you know that the RowMaps are different? I guess you could halt/log on the various steps. Is the object different from the registered copy. Does the mapping write the new value into the generated RowMap. Is the generated RowMap for the new version of this object different from the old one? Does the differencing produce a RowMap that contains the modified value? Does that modified value get written from the RowMap to the DB? RowMaps are not trivial to inspect, but should have all the information.

I'm a little bit suspicious of the explicit register, though it ought to be harmless. When you read within a unit of work things are automatically registered.

And actually thinking of the last couple of steps I wrote up there, is this a funny VA-specific object, where registration/lookup of the original object might not be working? Registration has to have special cases for the different ways that collections are implemented in different dialects. There could be others. Although if that was the reason I'd expect it to be easy to reproduce in isolation.


On Sun, Nov 1, 2020 at 8:20 PM Esteban Maringolo <[hidden email]> wrote:
Hi,

I have a weird situation where I can't find an easy way to debug (as usual).

Within a unit of work I read some object A from the DB, explicitly
#register: it in the session, modify some of its attributes, and then
commit the unit of work and the changes are not saved to the table.

Following the #register: message sends it ends up being registered as
an existing object (which is true), but I don't understand why the
changes are not applied afterwards since there are changes between the
read object (and hence its rowmap) and the new one.

Is there an easy way to debug this? This happens somehow deep in a ETL
and I can't find a way to reproduce it outside of the actual execution
of the ETL, so I want to identify the issue and then write the unit
test once the fix is done.

Thanks!

Esteban A. Maringolo

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/glorp-group/CAJMgPCJ8%3DuUWYFVH%3DaKVyCSqYd_wCmBVH4g2u0RNDaq63CgJrQ%40mail.gmail.com.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/glorp-group/262cb4cc-01a9-41fb-baf1-f17bbc6a2ca6n%40googlegroups.com.
Reply | Threaded
Open this post in threaded view
|

Re: Forcing save when #register: doesn't work

Esteban A. Maringolo
Hi Joachim,

There is no support for nested units of work, so the currentUnitOfWork in the inUnitOfWorkDo: block is going to be the same for what you call "a context" (which is the session).

Unless there is something else going on, which might also be the case :-)

Esteban A. Maringolo


On Tue, Nov 10, 2020 at 3:17 PM jtuchel <[hidden email]> wrote:
Esteban,

I am not sure I understand this line of code:

self inUnitOfWorkDo: [currentUnitOfWork registerAsNew: realObject]

doesn't currentUnitOfWork refernence the currentUnitOfWork of this context? And when you put it in the inUnitOfWorkDo: Block, that other unitOfWork is going to be the active unitOfWork, but not the one you thing it is? A stupid explanation, I know, let's try with a code example: I think your code is equivalent to this:

a:= self currentUnitOfWork.
self inUnitOfWorkDo: [a registerAsNew: realObject].

Or am I wrong? I would guess that the result looks different if you change your code to:

self inUnitOfWorkDo: [self privateGetCurrentUnitOfWork registerAsNew: realObject].


I've had a long day of debugging and not understanding a lot of what I observe, so please bear with me if this is total nonsense...

Joachim


[hidden email] schrieb am Montag, 9. November 2020 um 02:11:07 UTC+1:
Hi Alan,

Thanks for responding, I'm currently doing #forceSaveOf: and it is working.

forceSaveOf: anObject
"This is the same as registering an object, but it tells us to disregard whether/how the object has changed and to save all of its fields. This is useful if we need to register an object after changes have occurred, and can be used to implement something more like an object by object save facility. Still somewhat experimental."
  | realObject |
  realObject := self realObjectFor: anObject ifNone: [^self].
  self inUnitOfWorkDo: [currentUnitOfWork registerAsNew: realObject]

What I don't understand is why registering it as new still generates an UPDATE instead of an INSERT.

I know that objects read from the database are automatically registered, but since I do a lot of "read and if it doesn't exist then create it", and I treat both cases the same, so I do something like:

myPlayer := self readPlayerWithId: id ifNone: [self createNewPlayerWithId: id].
db register: myPlayer.

It is a simplified version of the code, but more or less it does the same for several objects that are sync'ed from an API.


Regards!

Esteban A. Maringolo


On Thu, Nov 5, 2020 at 10:55 AM Alan Knight <[hidden email]> wrote:
There is a debugRead/debugWrite type of variable on mappings that you can set, and you will get a halt when it reads or writes. That's probably the most useful hidden trick. But that will show you when it's being written to the RowMap. Do you know that the RowMaps are different? I guess you could halt/log on the various steps. Is the object different from the registered copy. Does the mapping write the new value into the generated RowMap. Is the generated RowMap for the new version of this object different from the old one? Does the differencing produce a RowMap that contains the modified value? Does that modified value get written from the RowMap to the DB? RowMaps are not trivial to inspect, but should have all the information.

I'm a little bit suspicious of the explicit register, though it ought to be harmless. When you read within a unit of work things are automatically registered.

And actually thinking of the last couple of steps I wrote up there, is this a funny VA-specific object, where registration/lookup of the original object might not be working? Registration has to have special cases for the different ways that collections are implemented in different dialects. There could be others. Although if that was the reason I'd expect it to be easy to reproduce in isolation.


On Sun, Nov 1, 2020 at 8:20 PM Esteban Maringolo <[hidden email]> wrote:
Hi,

I have a weird situation where I can't find an easy way to debug (as usual).

Within a unit of work I read some object A from the DB, explicitly
#register: it in the session, modify some of its attributes, and then
commit the unit of work and the changes are not saved to the table.

Following the #register: message sends it ends up being registered as
an existing object (which is true), but I don't understand why the
changes are not applied afterwards since there are changes between the
read object (and hence its rowmap) and the new one.

Is there an easy way to debug this? This happens somehow deep in a ETL
and I can't find a way to reproduce it outside of the actual execution
of the ETL, so I want to identify the issue and then write the unit
test once the fix is done.

Thanks!

Esteban A. Maringolo

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/glorp-group/CAJMgPCJ8%3DuUWYFVH%3DaKVyCSqYd_wCmBVH4g2u0RNDaq63CgJrQ%40mail.gmail.com.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/glorp-group/262cb4cc-01a9-41fb-baf1-f17bbc6a2ca6n%40googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/glorp-group/CAJMgPCJaWQN7GSDuLUFqkNHsHa12msAXrHJJ%2B8%3DG3bWVZ0QD-A%40mail.gmail.com.