OptimisticVerificationException (Row not found: GenericOID@) in Artificial types.

5 posts, 1 answers
  1. Vikash
    Vikash avatar
    14 posts
    Member since:
    Nov 2013

    Posted 04 Dec 2014 Link to this post

    I know this question has been raised multiple times with some solutions but not sure where my problem fits in.

    Based on my requirement, a user can create column on fly. For that, I am storing columns in some master table afterwards generating schema based on persistent types and then again re-generating context from artificial types kept under same master table.
    Sometime back I had posted example(which is solved now) on 
    http://www.telerik.com/account/support-tickets/view-ticket.aspx?threadid=836147
    http://www.telerik.com/account/ClientsFiles/ae8a07d5-d53a-40fe-9db6-3e937ea7db4e_ArtificialChangeTrackingV2.zip?accesskey=480EE467CF8E75A090468BF8DF8CB21DC2EF19EC&expires=635537024668437583

    When I add new column and do insert, it's working fine but failing on update with error:
    Telerik.OpenAccess.Exceptions.OptimisticVerificationException: Row not found: GenericOID@94811dfa TestTable Id=2

    UPDATE [TestTable] SET [ContactName] = ?, [EndDate] = ?,  [StartDate] = ?, [Test] = ?, [Test1] = ?, [Test3] = ?, [Test4] = ? WHERE [Id] = ? AND [ContactName] = ? AND [EndDate] = ?  AND [StartDate] = ? AND [Test] = ? AND [Test1] = ? AND [Test3] = ? AND [Test4] = ?
    (set event logging to all to see parameter values)
       at OpenAccessRuntime.ExceptionWrapper.Throw()
       at OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.handleException(Exception x, Boolean needsRollback)
       at OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.internalCommit(Boolean phase)
       at OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.commit()
       at Telerik.OpenAccess.OpenAccessContextBase.SaveChanges()
      
    Few things, that I have already tried:
    - Making column nullable. [http://www.telerik.com/forums/optimisticverificationexception-in-case-of-a-derived-class-looks-like-a-bug]
    - The persistent objects are generated on the fly so I have used SaveChanges(ConcurrencyConflictsProcessingMode.AggregateAll) but not working.[http://docs.telerik.com/data-access/feature-reference/api/context-api/feature-ref-api-context-api-managing-concurrency]

    Points that I am following:
    - Using fluent mapping.
    - New DbContext is initialized for each operation. (in this case insert or update are getting new context)

    Please let me know if any further explanation is required or if I have missed something.
  2. Vikash
    Vikash avatar
    14 posts
    Member since:
    Nov 2013

    Posted 04 Dec 2014 Link to this post

    It was getting 500 error while posting the question. If possible please delete the duplicates that got created.
  3. DevCraft banner
  4. Ady
    Admin
    Ady avatar
    588 posts

    Posted 09 Dec 2014 Link to this post

    Hi Vikash,

     I had a look at the example from the other post. What steps do I need to perform to reproduce the exception? 
    Can you update that example so that it reproduces the exception and send that or provide me with the required steps?

    Regards,
    Ady
    Telerik
     
    OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
     
  5. Vikash
    Vikash avatar
    14 posts
    Member since:
    Nov 2013

    Posted 15 Dec 2014 Link to this post

    Hello Ady,

    I have tried to make a simple example out of the previous example. I am able to re-produce same error that I was discussing, also removed some codes to focus on error. Please find SQL scripts under same zip file.

    I have added two ways to regenerate issue in one of them I doing reflection to achieve same.

    Please let me know if any other information is required.

    File location : https://www.dropbox.com/s/am5qz0lafbzh1fh/OptimisticVerificationExceptionV1.zip?dl=0

    Thank you,
    Vikash Kumar.
  6. Answer
    Ady
    Admin
    Ady avatar
    588 posts

    Posted 17 Dec 2014 Link to this post

    Hello Vikash,

      The 'Products' class (in your sample) uses 'Changed' Optimistic concurrency. In this mode DataAccess tries to update the row in the database which has the original values for the fields that have changed. You can see the UPDATE statement generated.
    The reason the update fails is that the artificial columns added at runtime are nullable but the CLR property which these columns are mapped to are all non-nullable. Ex - bit column is mapped to Boolean CLR property.

    The generated UPDATE statement tries to find a row with the CLR default value i.e 0 but the value in the column is NULL.

    I have updated the method that maps the artificial properties as follows - 

    var propType = Type.GetType(property.PropertyType);
                    if(propType.IsValueType)
                    {
                        propType = GetNullableType(propType);
                    }
                    var primitivePropertyConfiguration = myConfig.HasArtificialPrimitiveProperty(property.PropertyName,propType).HasFieldName(property.PropertyName);

     Here I check if the Type of the field is a value type and if it is, then I create a nullable CLR type instead of the non-nullable type.

    The helper method used is as below

    public static Type GetNullableType(Type type)
            {
                if (type.IsValueType)
                {
                    Type nullable = typeof(Nullable<>);
                    return nullable.MakeGenericType(new[] { type });
                }
                return type;
            }


     Do get back in case you need further assistance.

    Regards,
    Ady
    Telerik
     
    OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
     
Back to Top
DevCraft banner