AutoCloneOnUpdate - why?

AutoCloneOnUpdate - why?

Old forum URL: forums.lhotka.net/forums/t/7169.aspx


adamtuliper posted on Thursday, June 25, 2009

When dealing with large collections of objects a lot of the rule checking, etc causes out of memory errors when I was enumerating and reading properties because of authorization checks and objects created then in the background whenever I read properties. So I have bypassed them with a call to ReadProperty() instead.

Then when saving the object it was failing with an error that my class is not marked as serializable.

This was occuring because of the clone performed which eventually tries to serialize the object via

Csla.Core.ObjectCloner

I see I can simply add an item to the config file to bypass this although looking through the book I dont really see anything but a high level description of this value.

<add key="CslaAutoCloneOnUpdate" value="false"/>

Why is this the default behavior when saving an object, this seems it would  be quite a hit to have to serialize every object Im going to save. I dont want my object to be cloned, or serializable and I wouldn't imagine everyone would.. of course thats because I dont know the reason its included. Can someone provide some background on this and why its the default behavior?

Also .... in my case seems in

Csla.DataPortal.Update calls to Csla.Server.Dataportal.Update

The former determines the method name to call DataPortal_Update for ex. and then calls GetMethodInfo

The latter does the same work again.

Im not sure if this is necessary or not being fairly new to the framework.....just an observation since it was done twice.

Thanks!

 

 

 

JonnyBee replied on Thursday, June 25, 2009

Hi,

If you want your to code to be general - and work with any DataPortal - you should always consider the result of a Save to be a NEW instance your BO. The AutoCloneOnUpdate is for backward compatibility to older CSLA versions where the LocalPortal would not do an automatic clone.

And all DataPortals but the LocalPortal must Serialize your objects to send them to a remote server.

If you are using CSLA 3.6.x you should always check the FieldManger.FieldExists to check whether a LazyLoaded property is loded or not - not a good design to trigger LazyLoading in validation rules IMHO.  and you could also consider to add RelationshipType.LazyLoad on those PopertyInfo declarations. This will make CSLA throw an exception if you try to call ReadProperty or GetProperty on a LazyLoad field that has nott been set yet.

/jonny


adamtuliper replied on Thursday, June 25, 2009

for the "FieldManager.FieldExists" Im not sure if that was a general recommendation or response to my ReadProperty issue. If in response, Im not just talking about lazy loaded properties.. Im talking about a simple string field that already is loaded. I dont want any lazy loading with it. Its already set, but there are a bunch of behind the scenes creates that are not necessary for simple cases.. for instance, using GetProperty there is a "CanReadProperty" that is called which in turn create three dictionaries for every single object. One would think ok not that big of a deal, but in my case it caused me to run out of memory every time because of the number of objects I was dealing with. 

Im going to post another item now on performance.. as I think Im missing something. A simple test took fifty times longer using csla to save an object through dataportal_update than to call an update method directly, so I think there may be several things Im missing although Im following several samples and doing them the same way.

 

skagen00 replied on Thursday, June 25, 2009

Cloning is a brutal performance hit.

I had a fairly complex process written out that involved establishing multiple CSLA root objects and saving them...

Things seemed to take longer than I thought they should. I put ANTS profiler on it and a full 80% of my processing was attributable to the "Clone" calls. Put another way - cloning added a 400% performance hit.

That said, it certainly does address certain scenarios. But I wish it wasn't so costly myself.

In regards to your 50X claim, it would not surprise me if this is what you're seeing if you're running everything local to your machine. 50X seems high if your DB is on another box.

RockfordLhotka replied on Thursday, June 25, 2009

The core issue is in dealing with exceptions at the database level.

Consider the case where you have a collection of items. And where your database code saves around half the items and then fails.

And assume some of those items were new items, so the database code not only did an insert, but also put a database generated key value into the objects in memory.

And assume that you are using timestamp concurrency, so the database code updated the timestamps in every object in memory if the item was inserted/updated.

Now when the database operation fails, the database will rollback due to a database transaction. But your object graph in memory will be all messed up - it will have objects that think they were inserted/updated, and those objects will now have bogus key values and timestamps.

In short, you'll need to discard and reload the object graph. But if you do that, you'll lose all changes made by the user - eliminating any possibility for the user to retry the save, or to fix any issues and retry the save.

The cloning of the object graph before the save helps with this issue, by ensuring you can revert to the object graph as it was prior to the failed database operation.

bmmathe replied on Thursday, February 17, 2011

Rocky,

I have a recent post on the forum here: http://forums.lhotka.net/forums/t/10081.aspx where the AutoCloneOnUpdate isn't updating my object references on the root object being saved.

Why is this???  

When I set CslaAutoCloneOnUpdate to False, my references do get updated when the DP_Update returns.  The only problem with this is now if the save fails my objects won't automatically roll back like suggested in your post.

How can I keep CslaAutoCloneOnUpdate and have my object references keep the changes set in the DP methods?

Thanks for you help,

Brett

 

------UPDATE------

I found the root issue and was our fault.  On a Save() someone forgot to set the reference equal to the result of Save()...  Sorry.

Copyright (c) Marimer LLC