Answered by:
Verbose mode of SyncTracer

Question
-
I have a WinForms application that leverages Microsoft's Sync Framework v1.0. Specifically, these are the relevant references:
<Reference Include="Microsoft.Synchronization, Version=2.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Synchronization.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Synchronization.Data.Server, Version=1.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Synchronization.Data.SqlServerCe, Version=3.5.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL" />The app is an OCA employing a "Hub and Spoke" architecture. The hub is an Oracle server (10g) and each spoke is a SQL Server CE (3.5 SP1). The server table that I am synchronizing has the following schema and is provisioned using stored procedures:
CREATE TABLE "FIA"."PJ_TRACKING_EVENTS"
(
"PJ_EVENT_ID" NVARCHAR2(36) NOT NULL ENABLE,
"PLOT_ID" NUMBER(14,0) NOT NULL ENABLE,
"PJ_EVENT_TYPE_CD" NUMBER(2,0) NOT NULL ENABLE,
"PJ_EVENT_DATE" DATE DEFAULT TRUNC(CAST(SYS_EXTRACT_UTC(SYSTIMESTAMP) AS DATE)) NOT NULL ENABLE,
"PJ_RECIPIENT_CD" NUMBER(3,0) NOT NULL ENABLE,
"INSERTTIMESTAMP" TIMESTAMP (3) NOT NULL ENABLE,
"UPDATETIMESTAMP" TIMESTAMP (3) NOT NULL ENABLE,
"INSERTID" NUMBER DEFAULT 0 NOT NULL ENABLE,
"UPDATEID" NUMBER DEFAULT 0 NOT NULL ENABLE,
CONSTRAINT "PJTE_PK" PRIMARY KEY ("PJ_EVENT_ID") USING ... ENABLE,
CONSTRAINT "FK_PJTE_TO_EVENT_TYPES" FOREIGN KEY ... ENABLE,
CONSTRAINT "FK_PJTE_TO_PLOT_ASSGN" FOREIGN KEY ... ENABLE,
CONSTRAINT "FK_PJTE_TO_RECIPIENTS" FOREIGN KEY ... ENABLE
)Originally developed using Visual Studio 2008 & .Net 3.5, I am now in the process of upgrading to 2010 & 4.0. I moved all of the code over and targeted the 3.5 Framework and all works well. When I target the 4.0 Framework, I get all of the warnings that the System.Data.OracleClient is being deprecated. So, I have migrated to Oracle.DataAccess and I have also create a version using the Devart.Data.Oracle assembly. Synchronization continues to work, but not when I set the SyncTracer to Verbose (4). The following error is produced on the first call to Synchronize() when Oracle.DataAccess is used:
System.Reflection.TargetInvocationException was unhandled
Message=Exception has been thrown by the target of an invocation.
Source=mscorlib
StackTrace:
at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at Microsoft.Synchronization.Data.SyncTracer.TraceCommandParameter(Int32 indentLevel, DbParameter parameter)
at Microsoft.Synchronization.Data.Server.DbServerSyncProvider.SetSessionParameters(IDbCommand cmd, SyncGroupMetadata groupMetadata, SyncTableMetadata tableMetadata, SyncSession syncSession, DataColumnCollection columns, SyncStage stage, String commandName)
at Microsoft.Synchronization.Data.Server.DbServerSyncProvider.EnumerateChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession, IDbTransaction transaction, EnumerateChangeType changeType, SyncSchema traceSchema)
at Microsoft.Synchronization.Data.Server.DbServerSyncProvider.GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession)
at Microsoft.Synchronization.SyncAgent.DownloadChanges(SyncGroupMetadata groupMetadata)
at Microsoft.Synchronization.SyncAgent.DataSynchronize()
at Microsoft.Synchronization.SyncAgent.Synchronize()
at OraClientServerSync.Program.Main(String[] args) in C:\Users\Peter Gallati\Documents\Visual Studio 2010\Projects\ClientOraServerSync 11-28-10\ClientOraServerSync\Program.cs:line 54
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: Oracle.DataAccess.Types.OracleNullValueException
Message=Invalid operation on null data
Source=Oracle Data Provider for .NET
Number=-2502
StackTrace:
at Oracle.DataAccess.Types.OracleString.get_Length()
InnerException:And, when I use Devart.Data.Oracle, I receive a similar StackTrace and the error thrown is:
System.NullReferenceException was unhandled
Message=Object reference not set to an instance of an object.
Source=Microsoft.Synchronization.Data
StackTrace:
at Microsoft.Synchronization.Data.SyncTracer.TraceCommandParameter(DbParameter parameter)
at Microsoft.Synchronization.Data.Server.DbServerSyncProvider.SetSessionParameters(IDbCommand cmd, SyncGroupMetadata groupMetadata, SyncTableMetadata tableMetadata, SyncSession syncSession, DataColumnCollection columns, SyncStage stage)
at Microsoft.Synchronization.Data.Server.DbServerSyncProvider.EnumerateChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession, IDbTransaction transaction, EnumerateChangeType changeType, SyncSchema traceSchema)
at Microsoft.Synchronization.Data.Server.DbServerSyncProvider.GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession)
at Microsoft.Synchronization.SyncAgent.DownloadChanges(SyncGroupMetadata groupMetadata)
at Microsoft.Synchronization.SyncAgent.Synchronize()
at OraClientServerSync.Program.Main(String[] args) in C:\Users\Peter Gallati\Documents\Visual Studio 2010\Projects\ClientOraServerSync 11-25-10\ClientOraServerSync\Program.cs:line 52
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:From my experience with this problem, I believe that some parameter is null and cannot be handled by the Oracle.DataAccess or the Devart.Data.Oracle assemblies. I have enabled .Net Framework source stepping in Tools->Options->Debugging, but that didn't let me step into the Synchronize method.
QUESTION
How can I debug what is happening in the SyncTracer to find out what is causing this exception being thrown and how can I get my app running again with SyncTracer set to Verbose?
Help, please.
Tuesday, November 30, 2010 7:33 PM
Answers
-
Solved this problem on my own, after many agonizing hours. By comparing an old successful SyncTracer dump with the failed SyncTrace shown above, I noticed that the null value of sync_last_received_anchor was causing the exception. Modified the incremental insert, update, and delete procedures in the Oracle provisioning package to have the sync_last_received_anchor be an input instead of inputoutput parameter. Then, modified the ServerSyncProvider class (that inherits from DbServerSyncProvider) to have the Direction of the sync_last_received_anchor to be Input only and added the following line of code to set a default value for the sync_last_received_anchor parameter if it is null for the 3 incremental commands:
<Oracle command object for incremental insert, update, or delete>.Parameters[SyncSession.SyncLastReceivedAnchor].Value =
incUpdPjEventTrackingCmd.Parameters[SyncSession.SyncLastReceivedAnchor].Value ?? DateTime.MinValue.ToUniversalTime().ToString( "yyyy-MM-dd HH:mm:ss.fff" );
Rebuilt the solution and it runs successfully with SyncTracer set at Verbose level.
Life is good once again.
- Marked as answer by Peter G_ Friday, December 3, 2010 12:21 AM
Friday, December 3, 2010 12:20 AM