Ticket T493126
Visible to All Users
Duplicate

ModuleUpdater - How to avoid a NullReferenceException in the CreateCommand method with pooled database connections or a middle-tier application server

created 8 years ago (modified 8 years ago)

I updated my ObjectSpace providers to the following, per this blog post http://dennisgaravsky.blogspot.com/2017/03/xaf-app-performance-reducing-number-of.html

protected override void CreateDefaultObjectSpaceProvider(CreateCustomObjectSpaceProviderEventArgs args)
        {
            args.ObjectSpaceProviders.Add(new XPObjectSpaceProvider(XPObjectSpaceProvider.GetDataStoreProvider(args.ConnectionString, args.Connection, true), true));
            args.ObjectSpaceProviders.Add(new NonPersistentObjectSpaceProvider(TypesInfo, null));
        }

However, when attempting to call ExecuteNonQueryCommand in the Updater UpdateDatabaseBeforeUpdateSchema, it throws a NullReferenceException

Comments (1)

    System.NullReferenceException occurred
      HResult=0x80004003
      Message=Object reference not set to an instance of an object.
      Source=DevExpress.ExpressApp.v16.2
      StackTrace:
       at DevExpress.ExpressApp.Updating.ModuleUpdater.CreateCommand(String commandText)
       at DevExpress.ExpressApp.Updating.ModuleUpdater.ExecuteNonQueryCommand(String commandText, Boolean silent)
       at TattooStudio.ExpressApp.Module.Updater.UpdateDatabaseBeforeUpdateSchema() in C:\Source\REV23\TattooStudio\TattooStudio.ExpressApp\TattooStudio.ExpressApp.Module\DatabaseUpdate\Updater.cs:line 30
       at DevExpress.ExpressApp.Updating.DatabaseUpdaterBase.BeforeUpdateSchema(IList`1 moduleUpdaters)
       at DevExpress.ExpressApp.Updating.DatabaseUpdaterBase.UpdateCore(IObjectSpace updatingObjectSpace, IList`1 versionInfoList)
       at DevExpress.ExpressApp.Updating.DatabaseUpdater.Update()

    Answers approved by DevExpress Support

    created 8 years ago (modified 7 years ago)

    UPDATED:
    Starting with version 17.2.5, we improved our code to make ModelUpdater methods work correctly when data store pooling is specified in the connection string. Refer to the T587235 ticket for details.
    ==================
    When you pass True as the last argument of the XPObjectSpaceProvider.GetDataStoreProvider(e.ConnectionString, e.Connection, true) method, the data store pool is created as the top level connection provider. This "provider" internally maintains multiple connection providers, each of which uses its own database connection. These connections are not exposed outside the data store pool. So, the ModuleUpdater.CreateCommand method fails, as expected. So, you cannot use these built-in methods of the ModuleUpdater class (IsTableExists, DropTable, DropColumn, DropIndex, DropConstraint, RenameTable, RenameColumn, UpdateXPObjectType, DeleteObjectType) in this and similar scenarios. In general, these methods are legacy and specific to SQL Server only (they do not work for other database engines). So we are thinking about deprecating them in the future.

    If you need to perform some low-level tasks when there's no direct database connection, cast the object space to XPObjectSpace, access its Session and use corresponding methods of the Session class as described in the Direct SQL Queries help topic.

      Show previous comments (20)
      DevExpress Support Team 7 years ago

        You're right. In case of running DbUpdater, it is the main application, and ConfigurationManager accesses its configuration instead of the XAF application's one.
        As a general solution, you can pass the required information by declaring a static variable in the module or Updater class and initializing it in your XafApplication descendant constructor.
        Other possible solutions are:
        - Modify the DbUpdater source code (you can find it in "c:\Program Files (x86)\DevExpress 17.1\Components\Sources\DevExpress.ExpressApp.Tools\DBUpdater") to strip "XpoDataStorePool",  "XpoDataStorePoolSize", and  "XpoDataStorePoolMaxConnections" items from the connection string before passing it to the XafApplication instance.
        - Retrieve the underlying connection provider as described in the T426649 ticket.

          Thank you Michael!  The referenced ticket T426649 provided exactly what I needed.

          DevExpress Support Team 7 years ago

            Starting with version 17.2.5, we improved our code to make ModelUpdater methods work correctly when data store pooling is specified in the connection string. Refer to the T587235 ticket for details.

            Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

            Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.