SaaS CMS has officially launched! Learn more now.

Commerce Import XML uses the wrong CatalogID

Vote:
 

Hello,

I'm having a very ugly situation and I cannot find any kind of clue where the issue might be.

In few simple words, I'm trying to import a very basic XML having this structure:

<Catalogs Version="1.0">
	<Catalog name="XXX"	isActive="true"	defaultLanguage="en" defaultCurrency="eur" sortOrder="0" weightBase="kg" StartDate="2024-06-12">
		<Nodes totalCount="1">
			<Node>
				<Code>API1</Code>
				<Name>API1</Name>
				<StartDate>2024-06-12T11:02:11.682435Z</StartDate>
				<EndDate>2034-06-12T11:02:11.682471Z</EndDate>
				<IsActive>true</IsActive>
				<MetaData>
					<MetaClass><Name>CatalogCategoryModel</Name></MetaClass>
					<MetaFields>
						<MetaField>
							<Name>CategoryTitle</Name>
							<Type>ShortString</Type>
							<Data language="sv" value="Node 1"/>
						</MetaField>
						<MetaField>
							<Name>CategoryDescription</Name>
							<Type>LongHtmlString</Type>
							<Data language="sv" value="Aceasta este o descriere"/>
						</MetaField>
					</MetaFields>
				</MetaData>
				<ParentNode>Root_1</ParentNode>
				<SortOrder>0</SortOrder>
				<SeoInfo>
			      <Seo>
			        <LanguageCode>sv</LanguageCode>
			        <Uri>api1</Uri>
			        <Title>api1</Title>
			        <Description/>
			        <Keywords/>
			        <UriSegment>api11</UriSegment>
			      </Seo>
			    </SeoInfo>
			</Node>
		</Nodes>
	</Catalog>
</Catalogs>

The problem is pretty simple - I'm getting the following log messages:

[
    {
        "TimestampUtc": "2024-06-12T13:12:32.126993Z",
        "MessageType": 2,
        "Message": "Preparing to unpack zip file.",
        "StageName": "Extract",
        "StageIndex": 0,
        "StageCount": 2,
        "StageProgress": 0,
        "StageTotalProgress": 1055,
        "ExceptionMessage": null,
        "ExceptionStackTrace": null
    },
    {
        "TimestampUtc": "2024-06-12T13:12:32.129156Z",
        "MessageType": 2,
        "Message": "Unpacked zip file.",
        "StageName": "Extract",
        "StageIndex": 0,
        "StageCount": 2,
        "StageProgress": 1055,
        "StageTotalProgress": 1055,
        "ExceptionMessage": null,
        "ExceptionStackTrace": null
    },
    {
        "TimestampUtc": "2024-06-12T13:12:32.129468Z",
        "MessageType": 2,
        "Message": "Starting import...",
        "StageName": "Import",
        "StageIndex": 1,
        "StageCount": 2,
        "StageProgress": 0,
        "StageTotalProgress": 10000,
        "ExceptionMessage": null,
        "ExceptionStackTrace": null
    },
    {
        "TimestampUtc": "2024-06-12T13:12:32.129484Z",
        "MessageType": 2,
        "Message": "Start importing catalog nodes",
        "StageName": "Import",
        "StageIndex": 1,
        "StageCount": 2,
        "StageProgress": 3182,
        "StageTotalProgress": 10000,
        "ExceptionMessage": null,
        "ExceptionStackTrace": null
    },
    {
        "TimestampUtc": "2024-06-12T13:12:32.148927Z",
        "MessageType": 5,
        "Message": "The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_CatalogItem_Catalog\". The conflict occurred in database \"plattantwo-ecommerce\", table \"dbo.Catalog\", column 'CatalogId'.\nThe statement has been terminated.",
        "StageName": "Exception",
        "StageIndex": 1,
        "StageCount": 1,
        "StageProgress": 1,
        "StageTotalProgress": 1,
        "ExceptionMessage": "The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_CatalogItem_Catalog\". The conflict occurred in database \"plattantwo-ecommerce\", table \"dbo.Catalog\", column 'CatalogId'.\nThe statement has been terminated.",
        "ExceptionStackTrace": "   at System.Data.Common.DbDataAdapter.UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)\n   at System.Data.Common.DbDataAdapter.UpdatedRowStatus(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)\n   at System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping)\n   at System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows)\n   at Mediachase.Data.Provider.SqlDataProvider.<>c__DisplayClass19_0.<SaveRows>b__0()\n   at EPiServer.Data.Providers.SqlTransientErrorsRetryPolicy.Execute[TResult](Func`1 method)\n   at Mediachase.Data.Provider.SqlDataProvider.WithRetry[TResult](Func`1 action)\n   at Mediachase.Data.Provider.SqlDataProvider.SaveRows(DataCommand command)\n   at Mediachase.Data.Provider.SqlDataProvider.Save(DataCommand command)\n   at Mediachase.Data.Provider.DataService.Save(DataCommand command)\n   at Mediachase.Commerce.Storage.DataHelper.SaveTableSimpleWorker(DataCommand cmd, DataTable table, DataViewRowState state)\n   at Mediachase.Commerce.Storage.DataHelper.SaveDataSetSimple(DataCommand cmd, DataSet set, String[] tables)\n   at Mediachase.Commerce.Catalog.Data.CatalogNodeAdmin.Save()\n   at Mediachase.Commerce.Catalog.Managers.CatalogNodeManager.SaveCatalogNode(CatalogNodeDto dataset)\n   at Mediachase.Commerce.Catalog.Impl.CatalogContextImpl.SaveCatalogNode(CatalogNodeDto dto)\n   at Mediachase.Commerce.Catalog.ImportExport.Import.NodesReader.Save(CatalogNodeDto workingDto)\n   at Mediachase.Commerce.Catalog.ImportExport.Import.NodesReader.Read(ImportCatalogNodeCache relationCache)\n   at Mediachase.Commerce.Catalog.ImportExport.Import.Importer.Import(Stream stream, String sourceDirectory, Boolean overwrite)\n   at Mediachase.Commerce.Catalog.ImportExport.CatalogImportExport.Import(Stream stream, String directoryPath, Boolean overwrite)\n   at Mediachase.Commerce.Catalog.ImportExport.CatalogImportExport.Import(String directoryPath, Boolean overwrite)\n   at EPiServer.ServiceApi.Commerce.Jobs.CatalogImportJob.DoImport(String[] stages, Int32 stageIndex, String sourceDirectory)\n   at EPiServer.ServiceApi.Commerce.Jobs.CatalogImportJob.ExecuteJob(Guid jobId)"
    }
]

I connected to the development SQL server and I started the profiler in order to see what is being inserted in the CatalogNode table that generates the error and is pretty simple - the CatalogId is sent having the value 0.

I want to emphasize from the beginning that the catalog specified in the name attribute of the Catalog node exists and it has no problems.

I'm using the latest Commerce nuget packages:

EPiServer.Commerce: 14.22.0

EPiServer.ServiceApi: 7.1.0

EPiServer.ServiceApi.Commerce: 7.1.0

I don't understand what are the properties that are being used in order to identify the correct catalog where to insert the correct nodes.

Please, does anyone have any ideas?

Thank you,

Evdin

#323462
Jun 12, 2024 13:21
Vote:
 

Hi Evdin,

I guest this issue could be Catalog Name at catalog level is not existed in database then this catalog is added to database before importing node content. But the catalog id that used for imporitng node is not assigned again after saving new catalog to database.

Could you please confirm if that is your case? You could report a bug if it is the exact case that you are facing.

#323509
Jun 13, 2024 10:29
Vote:
 

Hello and thank you very much for your reply.

No, the catalog exists and is there with that given name. After doing some research (to be read that I banged my head against the wall), I discovered few things:

a) the import flow is very strange and the error message doesn't help at all - analyzing the order of the import steps I discovered that the issue might be in a total different place because the catalog itself wasn't analyzed from the XML point of view and the import process started directly with the node import.

b) the actual issue is just the fact that the XML it misses one line - please don't laugh but it's true - this is why the deserialization it's going nuts.

<?xml version="1.0" encoding="utf-8"?>

c) another important thing that it's not very well emphasized in the documentation is that, in order to have the existing catalog correctly identified, to have this node in your xml as a child for the catalog node:

<Languages>
	      <Language>
	        <LanguageCode>en</LanguageCode>
	        <UriSegment>xxx</UriSegment>
	      </Language>
	    </Languages>

Yes, that was it!!! Pretty simple but the errors are so wrongly served... :-(

Thank you again,

Evdin

#323510
Jun 13, 2024 10:43
Vote:
 

Great finding, Edin!

#323554
Jun 14, 2024 7:19
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.