locked
Custom DbSyncProvider getting ReplicaId cannot be null. RRS feed

  • Question

  • Hi everyone!

    I am currently trying to do a synchronization using a sync framework with 2 firebird databases (I know... isn't usual).

    So I created a custom class wich descend from DbSyncProvider and created the scope_info table. I implemented the
    custom commands in my constructor as you can see below:

            public CustomSyncProvider(string scope, string connectionString)
            {
                ScopeName = scope;
    
                Connection = new FbConnection(connectionString);
                Connection.Open();
    
                SelectNewTimestampCommand = Connection.CreateCommand();
                SelectNewTimestampCommand.CommandText = "execute procedure GET_TIME_STAMP";
                var ts = SelectNewTimestampCommand.CreateParameter();
                ts.Direction = ParameterDirection.Output;
                ts.ParameterName = "@sync_new_timestamp";
                SelectNewTimestampCommand.CommandType = CommandType.StoredProcedure;
                SelectNewTimestampCommand.Parameters.Add(ts);
    
                SelectScopeInfoCommand = Connection.CreateCommand();
                ScopeForgottenKnowledgeColName = "SCOPE_TSTONE_CLEANUP_KNOWLEDGE";
                SelectScopeInfoCommand.CommandType = CommandType.Text;
                SelectScopeInfoCommand.CommandText = "select " +
                                               @"SCOPE_LOCAL_ID ,
                                                SCOPE_ID ,
                                                SCOPE_NAME ,
                                                SCOPE_SYNC_KNOWLEDGE ,
                                                SCOPE_TSTONE_CLEANUP_KNOWLEDGE ,
                                                SCOPE_TIMESTAMP,
                                                SCOPE_CLEANUP_TIMESTAMP from scopeinfo " +
                                                "where scope_name = @" + DbSyncSession.SyncScopeName;
    
                SelectScopeInfoCommand.Parameters.Clear();
    
                var scopeParameter = SelectScopeInfoCommand.CreateParameter();
                scopeParameter.ParameterName = "@" + DbSyncSession.SyncScopeName;
                SelectScopeInfoCommand.Parameters.Add(scopeParameter);
    }

    But when I call the method Synchronize() from SyncOrchestrator, I get  the exception "Value cannot be null. Parameter name replicaId". 

    I already made tests with SqlSyncProvider and works like a charm.

    Anyone have an idea?

    Thanks in advance and sorry for my bad english.



    Here is the stack trace.
    "   em Microsoft.Synchronization.SyncIdFormat.ValidateArgument(SyncId id, String argumentName, String errorMessage)\r\n   em Microsoft.Synchronization.SyncKnowledge..ctor(SyncIdFormatGroup idFormats, SyncId replicaId, UInt64 tickCount)\r\n   em Microsoft.Synchronization.Data.SyncScopeHandlerBase.GetCurrentKnowledge()\r\n   em Microsoft.Synchronization.Data.DbSyncScopeHandler.ReadScope(IDbConnection connection, IDbTransaction transaction, ReadKnowledgeType readType, ReadForgottenKnowledgeType readFKtype)\r\n   em Microsoft.Synchronization.Data.SyncScopeHandlerBase.ReadScope(IDbConnection connection, ReadKnowledgeType readType)\r\n   em Microsoft.Synchronization.Data.RelationalSyncProvider.GetScope(DbSyncSession DbSyncSession)\r\n   em Microsoft.Synchronization.Data.RelationalSyncProvider.GetSyncBatchParameters(UInt32& batchSize, SyncKnowledge& knowledge)\r\n   em Microsoft.Synchronization.KnowledgeProviderProxy.GetSyncBatchParameters(ISyncKnowledge& ppSyncKnowledge, UInt32& pdwRequestedBatchSize)\r\n   em Microsoft.Synchronization.CoreInterop.ISyncSession.Start(CONFLICT_RESOLUTION_POLICY resolutionPolicy, _SYNC_SESSION_STATISTICS& pSyncSessionStatistics)\r\n   em Microsoft.Synchronization.KnowledgeSyncOrchestrator.DoOneWaySyncHelper(SyncIdFormatGroup sourceIdFormats, SyncIdFormatGroup destinationIdFormats, KnowledgeSyncProviderConfiguration destinationConfiguration, SyncCallbacks DestinationCallbacks, ISyncProvider sourceProxy, ISyncProvider destinationProxy, ChangeDataAdapter callbackChangeDataAdapter, SyncDataConverter conflictDataConverter, Int32& changesApplied, Int32& changesFailed)\r\n   em Microsoft.Synchronization.KnowledgeSyncOrchestrator.DoOneWayKnowledgeSync(SyncDataConverter sourceConverter, SyncDataConverter destinationConverter, SyncProvider sourceProvider, SyncProvider destinationProvider, Int32& changesApplied, Int32& changesFailed)\r\n   em Microsoft.Synchronization.KnowledgeSyncOrchestrator.Synchronize()\r\n   em Microsoft.Synchronization.SyncOrchestrator.Synchronize()\r\n   em Autobyte.Sync.Client.FormStatus.button2_Click(Object sender, EventArgs e) na 



    Monday, January 25, 2010 1:40 PM

Answers

  • Charles,

    Can you try tomake your scope_id a uniqueidentifier insate instead of a varchar(100) NOT NULL.
    The data type difference maybe the root cause of it.

    Also is there any specific reason you are using the 2 firebird database?
    The SQL providers we have out of the box work fine with the SQL Server SKUs - whether they are paying SKUs or the free SKUs: SQL Express and SQL Compact.
    This posting is provided AS IS with no warranties, and confers no rights
    Sunday, February 7, 2010 11:30 PM

All replies

  • I suggestion is to profile the TSQL executed on the server during the .Synchronize() execution.

    Please profile the TSQL when SqlSyncPrvider is used in Sync, which was good.
    Please profile the TSQL when the customized provider is used in Sync, which raises an exception.

    And see if you can find the difference from the TSQL sent to the SQL Server during .Synchronize().

    Thanks.
    Leo Zhou ------ This posting is provided "AS IS" with no warranties, and confers no rights.
    Monday, January 25, 2010 6:40 PM
    Answerer
  • Thanks Zhou. 

    I have profiled the SqlSyncAdapter and my application. I really don´t know what is going wrong. I also tried with SQLite adapter without success. Both custom providers fall in same point.



    Tuesday, January 26, 2010 8:51 PM
  • What did you get when executing "select

     

    scope_id, * from dbo.scope_info" in the source replica database?

    Thanks.


    Leo Zhou ------ This posting is provided "AS IS" with no warranties, and confers no rights.
    Wednesday, January 27, 2010 12:24 AM
    Answerer
  • Thank for your attention.


    Zhou, I have the following sql statement :

    "SELECT scope_id, scope_local_id, scope_sync_knowledge, scope_tstone_cleanup_knowledge, scope_timestamp, scope_config_id, scope_restore_count FROM scope_info WHERE scope_name = @" + DbSyncSession.SyncScopeName

    this statement runs against this table:


    CREATE TABLE SCOPE_INFO (
        SCOPE_LOCAL_ID                  INTEGER NOT NULL,
        SCOPE_ID                        VARCHAR(100) NOT NULL,
        SCOPE_NAME                      VARCHAR(100) NOT NULL,
        SCOPE_SYNC_KNOWLEDGE            BLOB SUB_TYPE 0 SEGMENT SIZE 80,
        SCOPE_TSTONE_CLEANUP_KNOWLEDGE  BLOB SUB_TYPE 0 SEGMENT SIZE 80,
        SCOPE_TIMESTAMP                 TIMESTAMP,
        SCOPE_CONFIG_ID                 VARCHAR(100),
        SCOPE_RESTORE_COUNT             INTEGER,
        SCOPE_CLEANUP_TIMESTAMP         INTEGER
    );

    Note, BlOB SUB_TYPE 0 is the binary blob from firebird, I already tested with the TEXT blob without success.


    and I have populated this table with  this statement:



    INSERT INTO SCOPE_INFO 
    (SCOPE_LOCAL_ID, SCOPE_ID, SCOPE_NAME, SCOPE_SYNC_KNOWLEDGE, SCOPE_TSTONE_CLEANUP_KNOWLEDGE, SCOPE_TIMESTAMP, SCOPE_CONFIG_ID, SCOPE_RESTORE_COUNT, SCOPE_CLEANUP_TIMESTAMP) 
    VALUES
     (1, 'ccf564d9-5198-45be-9727-c7c6950f410a', 'Atbt', NULL, NULL, '30-DEC-1899 00:00:00', '7aa4f510-fdf2-4c58-8f44-f263b0c0a0bd', 0, 1);



    But the exception remains the same (This one is from SyncTracer):


    VERBOSE, Autobyte.Sync.Client, 1, 01/26/2010 02:04:57:790,    Executing Command: SELECT scope_id, scope_local_id, scope_sync_knowledge, scope_tstone_cleanup_knowledge, scope_timestamp, scope_config_id, scope_restore_count FROM scope_info WHERE scope_name = @sync_scope_name
    VERBOSE, Autobyte.Sync.Client, 1, 01/26/2010 02:04:57:792,       Parameter: @sync_scope_name Len: 4 Value: Atbt
    ERROR  , Autobyte.Sync.Client, 1, 01/26/2010 02:04:57:898, Caught exception while getting scope: System.ArgumentNullException: Valor não pode ser nulo.
    Nome do parâmetro: replicaId
       em Microsoft.Synchronization.SyncIdFormat.ValidateArgument(SyncId id, String argumentName, String errorMessage)
       em Microsoft.Synchronization.SyncKnowledge..ctor(SyncIdFormatGroup idFormats, SyncId replicaId, UInt64 tickCount)
       em Microsoft.Synchronization.Data.SyncScopeHandlerBase.GetCurrentKnowledge()
       em Microsoft.Synchronization.Data.DbSyncScopeHandler.ReadScope(IDbConnection connection, IDbTransaction transaction, ReadKnowledgeType readType, ReadForgottenKnowledgeType readFKtype)
       em Microsoft.Synchronization.Data.SyncScopeHandlerBase.ReadScope(IDbConnection connection, ReadKnowledgeType readType)
       em Microsoft.Synchronization.Data.RelationalSyncProvider.GetScope(DbSyncSession DbSyncSession)


    That is all I got.

    I don´t know if I created  the scope_sync_knowledge field with the right data type, but it is null after all. 

    All that I know is:

       em Microsoft.Synchronization.SyncKnowledge..ctor(SyncIdFormatGroup idFormats, SyncId replicaId, UInt64 tickCount)
       em Microsoft.Synchronization.Data.SyncScopeHandlerBase.GetCurrentKnowledge()

    The replicaId parameter is null when the method GetCurrentKnowLedge calls the SyncKnowlege constructor.



    Thank you very much Zhou.

    --I don´t get the sync work yet..
    Wednesday, January 27, 2010 1:16 AM
  • Charles,

    Can you try tomake your scope_id a uniqueidentifier insate instead of a varchar(100) NOT NULL.
    The data type difference maybe the root cause of it.

    Also is there any specific reason you are using the 2 firebird database?
    The SQL providers we have out of the box work fine with the SQL Server SKUs - whether they are paying SKUs or the free SKUs: SQL Express and SQL Compact.
    This posting is provided AS IS with no warranties, and confers no rights
    Sunday, February 7, 2010 11:30 PM
  • Hi everybody,

    I'm having the same problem and in my case the scope_id is uniqueidentifier.
    I'm using two postgre databases.

    I tried setting all the fields in the ScopeInfo table but still says that ReplicaId cannot be null.

    Any help is valid.

    Thanks.
    Friday, February 19, 2010 1:49 PM
  • Hi,
    Not sure all about this but VARCHAR(100) for scope_id ... Hm.. Firebird does not support natively uniqueidentifiers and everything around says to replace it witch CHAR(16) type (uniqueids in MS Sql are 16 byte length in storage as well). From ver. 2.0 of Firebird  there is GEN_UUID() which handles creation of 16 bytes length values (same as guids but no dashes). I guess there can be conversion problem between VARCHAR(100) and SyncId (internally 16 byte buffer), externally Guid class of .Net. Small change you can try to do is to replace SCOPE_INFO table def. in firebird.
    Second think is timestamp used in table definition. Not 100% sure here but Microsoft timestamp sql datatype (referenced on MSDN docs) was in fact bigint,  but in Firebird timestamp is DataTime type. You can try with it but you can also replace timestamp type with bigint and populate it with e.g. current_transaction which is bigint database global variable (again conversion in mind). I' not an expert so really this is my best shot without full steps to repro.

    Cheers,
    Eryk
    Eryk
    Monday, March 1, 2010 1:51 AM
  • Finally I managed this on my side. I replicated Firebird with SQL server express using DbSyncProviders. Secret at Firebird side: almost all the time use Stored Procedures.
    and follwoing conversions work out of the box:

    MS Sql timestamp ->bigint on Firebird.
    uniqueidentifier -> Char(16) CHARACTER SET OCTETS e.g. SYNC_SCOPE_ID Char(16) CHARACTER SET OCTETS
    varbinary -> Char(8000) CHARACTER SET OCTETS e.g. SYNC_SCOPE_KNOWLEDGE Char(8000) CHARACTER SET OCTETS


    Cheers,
    Eryk
    Eryk
    Friday, March 5, 2010 4:02 AM
  • Thank you very much Eryk,

    I will try this changes and post here if works.

     

     

    Thursday, March 25, 2010 6:27 PM
  • Hello could anyone post an example of the custom DbSyncProvider. I would be very thankfull. I could post my email and you could send the exampe to me if you can or just share the files on internet.
    Tuesday, September 4, 2012 6:55 AM
  • Hello could anyone post an example of the custom DbSyncProvider. I would be very thankfull. I could post my email and you could send the exampe to me if you can or just share the files on internet.
    Tuesday, September 4, 2012 6:55 AM