Entity lifecycle or can IsNew "magically" revert back to true after save.

Posts   
 
    
Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 20-Jan-2010 20:26:21   

Assuming the latest version of LLBLGen runtime:

I have an

var entity = new MyEntity(new Guid());

shared across threads. I'm saving it initially (single thread) using:

adapter.SaveEntity(entity, false, true);

and assert entity.IsNew is false.

Then the threads get at it changing some of the fields (never touching the IsNew property). Is it possible at all that during the next:

adapter.SaveEntity(entity, false, true);

entity.IsNew will be true (for even the slightest fraction of a second) making the runtime think the it should do an insert instead of an update? My assumption would be IsNew will remain false after the first save (and thus generate updates) but we are experiencing this very problem in our application which makes me wonder whether internally it does get changed.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 21-Jan-2010 01:49:34   

Looks like a thread related issue. You maybe should place a lock surrounding the initialization and first save code.

David Elizondo | LLBLGen Support Team
Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 21-Jan-2010 07:14:15   

daelmo wrote:

Looks like a thread related issue. You maybe should place a lock surrounding the initialization and first save code.

Thanks for you answer. As I initially mentioned I am curious about the possibility of IsNew being set back to true after initial single threaded save (when we're 100% sure it was saved and has its IsNew = false before any other thread attempts a save). Is there any piece of code in LLBLGen internals that could do that (modifying data properties / adding to child collections) even for a fraction of second or is IsNew "immutable" once set to false (and not explicitly changed by me)?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 21-Jan-2010 10:08:50   

IsNew is never set to true by code after a save, only to false. So it comes down to how you have scheduled the consumption of these entities by persistence logic: are all entities saved by a single adapter?

Frans Bouma | Lead developer LLBLGen Pro
Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 21-Jan-2010 12:14:38   

Otis wrote:

IsNew is never set to true by code after a save, only to false.

Thanks, Frans - this will make our bug hunting more targeted.

Otis wrote:

So it comes down to how you have scheduled the consumption of these entities by persistence logic: are all entities saved by a single adapter?

adapters are always created before the save and used only for that single operation - they are never shared across threads.

we event try lock (entity.OurLockingObject){ save here } to make sure there's only one save going on at a time (others can modify the entity during the save however) but we still get ocassional inserts instead of updates.

I don't know if the fact that we are not refetching after save or using uniqueidentifier as the key (set in code not in db) significant here because it usually works so I don't expect this to be the reason (as I understand that's a completely valid use case with LLBLGen).

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 21-Jan-2010 12:25:47   

That seems like a valid use.

I think somewhere in your code. You instantiate a new entity, and then you set the PK (of an existing entity) in code as you say. At this point of time, the entity will have IsNew = true, unless you fetch it from the database. And that's because you are using Adapter. If it was SelfServicing, once you pass the PK value in the CTor of the entity it gets fetched and IsNew will be set to false.

So maybe the above is the case, especially if the code was ported from SelfServicing to Adapter.