entity validation and exception cost

Posts   
 
    
nilsey
User
Posts: 54
Joined: 11-Jan-2008
# Posted on: 08-May-2012 23:42:55   

we're looking at setting up some patterns for validating entities upon Save. In the LLBL documentation the standard put forth is to validate a field, and if not valid throw an ORMEntityValidationException.

The way i'm thinking about validation here is: do the fields follow some business rules (i.e. which fields are required, what rules must they respect such as, which must be unique in teh database etc.)

one of my colleagues makes the point that raising exceptions is a pretty expensive operation, and is something we shouldn't do for things we really expect to happen often (like a field not following a business rule). He has pointed me to this article as an example of the argument against using exceptions for the purposes of validation:

http://blogs.msdn.com/b/ricom/archive/2003/12/19/44697.aspx

Can you offer any argument in favor of throwing an exception in these cases?

it occurred to me that one possibility would be simply to provide a method to cancel the save operation with a potential argument indicating a reason (or list of reasons).

for example:


        Protected Overrides Sub OnValidateEntityBeforeSave()
            ''
            Dim exceptionMessages As New List(Of String)
            If Not Me.SomeXXXFieldIsNotValid() Then
                exceptionMessages.Add( "The XXX field is not valid. ")
            End If

            If Not Me.SomeYYYFieldIsNotValid() Then
                exceptionMessages.Add( "The YYY field is not valid. ")
            End If
            '' other validation etc

            '' here we interrupt teh save itself so it returns false - this is teh proposed method
            If exceptionMessages.count > 0 Then
                Me.CanceSave(exceptionMessages) '' this is not a real method
            End If


            MyBase.OnValidateEntityBeforeSave()
        End Sub

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 09-May-2012 09:58:57   

As validation happens at a location (e.g. in a validator object) where no access is present to whatever logic which called the validation, the only way to abort the action of the caller is to throw an exception. Also, a save operation's outcome if something is wrong can only be total abortion of the action, so an exception thrown is the least of the problems, and the little overhead of an exception is really not noticed when you compare it with rolling back the transaction. The exception makes it easy to cancel the operation, as a lot can happen during the save operation, and the only solid way to make the save operation abort is by throwing an exception.

While an exception is not as fast as a normal if statement, one shouldn't exaggerate the slowness of it, it's not as if you'll notice it if an exception is thrown. In a loop, sure, but that's not what's happening here.

If you want to validate a field's value before it's set (the right place to do so), you don't need exceptions. The built-in validation pipeline calls into OnValidateFieldValue, which calls into an existing Validator object in the entity, if present, otherwise it simply returns true. You can override this method if you want, in a partial class of the entity.

This method simply returns true or false. If false, the field isn't set with the value. You can set the error message on the field using the SetEntityFieldError method.

Aren't you mixing two things in your post? Namely field set validation and save validation?

Frans Bouma | Lead developer LLBLGen Pro