IsDirty problem when moving from CSLA 2.1.4 to CSLA 3.6.3

IsDirty problem when moving from CSLA 2.1.4 to CSLA 3.6.3

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


frankhoffy posted on Monday, July 13, 2009

I have a fairly large application that I would like to upgrade from CSLA 2.1.4 to 3.6.3.  I haven't changed the code at all; I've simply updated the reference to CSLA.

There seems to have been a change to the way state management works when trying to determine if something is dirty, but I can't track down exactly where the problem is occurring.

The current UI is calling the ApplyEdit and Save methods, but immediately after the Save method, the object still reports itself as being dirty.

Any suggestions on where I need to look would be helpful.  If I can't figure this out, we may be stuck in CSLA 2.1.4 for a while.

RockfordLhotka replied on Monday, July 13, 2009

You are probably encountering one of the highlighted breaking changes from version 3.5 - the AutoCloneOnUpdate behavior.

You can search for that word and find it discussed over the past 2-3 years.

In CSLA 3.0 AutoCloneOnUpdate was added, with a default of false - which preserved backward compatibility.

A year or so later, in version 3.5, the default was changed to true - which breaks backward compatibility unless you add a config file entry to make it false.

The idea of AutoCloneOnUpdate is to ensure the local data portal provides (nearly) the same semantic behavior as the remote data portal, so the Save() method returns a new instance of the object if the operation succeeds.

This was done to avoid two of the biggest issues people were facing 2-3 years ago. The first is that it wasn't transparent to switch between local and remote data portal code, because it was possible to write (technically incorrect) client code that ignored the result of Save(). The second is that correct UI code not only used the result of Save(), but had a bunch of exception handling to deal with the case where the database update failed in the middle.

Since most people didn't write correct data portal code when using a local data portal, I phased in AutoCloneOnUpdate over a 2 year period to "encourage" people to write correct UI code - and to simplify what was meant by "correct UI code".

You have two choices - either add an entry in your config file to set AutoCloneOnUpdate to false, or fix your UI code so it is correct.

Obviously if your current code is working for you, you may not see this as a "fix", which is why the switch exists to get the older behavior :)

frankhoffy replied on Monday, July 13, 2009

Thanks for the prompt reply Rocky.  Adding the config file entry got around that issue.

I could tell that state management had changed a bit.  I also had to get rid of a BeginEdit call due to an Edit level mismatch exception.

You've done a really good job of adding a lot of new features to the framework yet still making it backwards compatible.  Thanks for all of your hard work.  It has really made a difference in our organization.

JoeFallon1 replied on Monday, July 13, 2009

FYI - the config file entry needs to be a very short term solution. i.e. use it only to compile the app while you hunt down the real issue.

And it is a simple issue. In fact it is the #1 bug in the code of users of CSLA.

You must have written code like this:
myBO.Save()

That is a bug in your code! If you ever switch the dataportal to a remote scenario your code will be broken! That is why Rocky added the autocloneonupdate feature.

Your code simply needs to be changed to this:
myBO = myBO.Save()

===================================================================

On a similar note I ran into an IsDirty issue recently - I have converted a large web app from CSLA 2.1 to 3.6 and noticed that some classes didn't work right. The reason is that the DataPortal calls MarkNew and then Create. It also calls MarkOld and then Fetch.

My classes "normally" call one of the Mark methods at the end of Create or Fetch and then called check rules. But for some hand coded classes I relied on the older behavior where the dataportal did not call them for you. So in a Fetch when I omitted MarkOld, the BO acted as if I had called MarkNew and it was then used in my app that way. After the upgrade - it broke because now the framework called MarkOld.

I had two ways to fix it - one was to call MarkNew at the end of a fetch - which would be silly. The other was to move the code to DataPortal_Create instead of Fetch and let the framework do its thing. That is what I did.

Joe

 

 

 

 

 

 

frankhoffy replied on Monday, July 13, 2009

Well I hope the config setting stays around for a bit, because the alternate route does have some ramifications to our code.  This is a WPF application that has some properties that are flow documents.  Flow documents can't be serialized, so getting the new object reference from the Save method causes all of those values to be null.  That means we would have to fetch the data from the database again and rebind.

The object is also being passed in from another form that has a grid with a ModifiedDate column.  Updating the object reference would make us have to update that grid as well.

None of these issues are the end of the world, but they do cause an additional performance hit.  We had some issues with memory consumption with our flow documents.  The config file setting is a nice way for us to retain our current functionality and still move forward with the new version of the library.

JoeFallon1 replied on Monday, July 13, 2009

That is OK. Just so you understand the ramifications of your decision - you can't ever use a remote DataPortal for your app. You may not plan to now - but you won't ever be able to in the future if a use case comes up where it is required. If you are fine with that then drive on!

Joe

Copyright (c) Marimer LLC