Diagnosing ORMEntityOutOfSyncException errors

Posts   
 
    
Posts: 8
Joined: 15-Jan-2009
# Posted on: 09-Mar-2009 18:30:34   

We are getting an ORMEntityOutOfSyncException error during the commit of a large (1000+ entity) UnitOfWork2. It's being very difficult to diagnose because we can't pinpoint any particular entity as causing the trouble. Is there any way to do this? The error is happening in a production system and we can't reproduce it in our development environment for debugging.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 10-Mar-2009 06:27:57   

Hi Jeff,

Please post more info (http://llblgen.com/tinyforum/Messages.aspx?ThreadID=7725) as: - LLBLGen version and runtime library version. - Exact error message and stack trace. - Code snippet where you got this error.

David Elizondo | LLBLGen Support Team
Posts: 8
Joined: 15-Jan-2009
# Posted on: 25-Mar-2009 13:43:15   

Sorry for the lack of specific information. I wasn't really asking for a specific diagnosis of my situation, but rather looking for general guidance on how to diagnose these kinds of errors. Turns out in my situation:

  • I had a large unit of work, with a commit order of [insert, update, delete].
  • I called AddForSave with an entity, telling it to recurse but not to refetch, since I never used the entity after it was persisted.
  • This entity had a child entity, for which IsNew == true.
  • This entity also had validations which looked at said child entity. Since the child entity was new, it got inserted and marked out of sync, so when the entity was to be updated, the validations fired and threw an ORMEntityOutOfSyncException. Now under these circumstances, the stack trace was completely useless; all I saw was an exception coming out of UnitOfWork2.Commit(); the exception contained no information about what entity is out of sync or why; tracing/logging dumps a list of thousands of entities to sift through, again with no indication of which entity is out of sync; and basically, it was impossible to diagnose. I figured that turning on refetching would probably fix the issue (which it did), but then I would have had no idea why this was necessary or under what circumstances the problem occurred. What I ended up having to do was to get a copy of production data (since we could not reproduce this issue in development or QA), make a custom debug build of the runtime libraries, step through the code and perform a binary search to find exactly from where the exception was being thrown. This seems less than optimal. Am I missing something? Is there a tool that I could have used to more effectively diagnose this problem?
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39859
Joined: 17-Aug-2003
# Posted on: 25-Mar-2009 15:59:08   

I find it a bit odd that the stacktrace doesn't reveal the origin of the exception, did you also examine the inner exception?

Anyway, I think why this happens as you also described: entity X gets inserted, is marked as outofsync, validator of other entity looks at fields of X, this triggers the outofsync error.

The exception class itself is not really helpful in all cases indeed, that is: it's sufficient for the main reason it's thrown: some code reads a property of an entity which isn't refetched, this is easy tracked down by a stacktrace. However in your case, this isn't really sufficient, you need the original entity.

I think if we pass in the entity which caused the exception to throw, it would be more sufficient. I'll make a change request for this.

Now, back to your problem. There's an easy shortcut for getting entities marked as fetched after a save, instead of simply refetching them which can be performance intense and unnecessary if you don't need it. See: Entity2.MarkSavedEntitiesAsFetched and this documentation page.

In short, it simply marks a saved entity as 'fetched', so you don't run into the problem with outofsync anymore. it's a global setting, though in almost all cases you're fine. The only cases to be careful with is when you have default values /constraints defined in the database and you don't set these fields to a value AND you access the entity after the save: the entity then has to be refetched: before you'd get an exception (out of sync) and with this setting you won't.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 8
Joined: 15-Jan-2009
# Posted on: 25-Mar-2009 16:11:14   

Otis wrote:

I find it a bit odd that the stacktrace doesn't reveal the origin of the exception, did you also examine the inner exception?

I did. It's been a little while since I diagnosed the issue, though, and I can't remember why it didn't reveal anything.

Otis wrote:

I think if we pass in the entity which caused the exception to throw, it would be more sufficient. I'll make a change request for this.

Wonderful! Thanks.

Otis wrote:

Now, back to your problem. There's an easy shortcut for getting entities marked as fetched after a save, instead of simply refetching them which can be performance intense and unnecessary if you don't need it. See: Entity2.MarkSavedEntitiesAsFetched and this documentation page.

In short, it simply marks a saved entity as 'fetched', so you don't run into the problem with outofsync anymore. it's a global setting, though in almost all cases you're fine. The only cases to be careful with is when you have default values /constraints defined in the database and you don't set these fields to a value AND you access the entity after the save: the entity then has to be refetched: before you'd get an exception (out of sync) and with this setting you won't.

Thanks. I'm not terribly worried about the performance, so I just made it refetch. However, I'm pretty sure we don't actually need refetching in our app; so maybe we'll use this instead.