Absolutely split the migration into separate jobs - this is the correct approach for cost accounting data. Let me explain the complete solution covering your ETL job structure, duplicate key prevention, and cost center table handling.
ETL Job Restructuring:
Your duplicate key error stems from trying to import both master data and dimensional relationships in a single pass. Cost accounting in D365 requires a specific import sequence:
-
Job 1 - Cost Center Master Data:
- Entity: `CAMCostCenterEntity
- Fields: CostCenterID, Name, Description, Type, Status
- Mode: Insert or Upsert
- This creates the base cost center records without dimensions
-
Job 2 - Dimension Definitions:
- Entity: `CAMDimensionEntity
- Import dimension members (AREA-NORTH, AREA-SOUTH, etc.) if not already present
- Must complete before Job 3
-
Job 3 - Cost Center Dimension Associations:
- Entity: `CAMCostCenterDimensionEntity
- Fields: CostCenterID, DimensionName, DimensionValue
- This creates the composite key combinations
- Enable “Skip duplicate” option in execution settings
Duplicate Key Error Resolution:
The composite primary key (CostCenterID, DimensionName, DimensionValue) is causing your violations. Address this with:
- Pre-Import Validation Query:
SELECT CostCenterID, DimensionName, DimensionValue, COUNT(*)
FROM StagingTable
GROUP BY CostCenterID, DimensionName, DimensionValue
HAVING COUNT(*) > 1
This identifies duplicates in staging before import execution.
- Clear Target Table Strategy:
Even if the table appears empty, dimension combination records might exist in related tables:
DELETE FROM CAMCostCenterDimensionCombination
WHERE CostCenterID IN (SELECT CostCenterID FROM CAMCostCenter)
DELETE FROM CAMCostCenter
Run this cleanup script before migration to ensure truly clean state.
- Parallel Processing Configuration:
Disable parallel processing for cost center imports:
- Data Management > Framework Parameters
- Set “Maximum insert commit size” to 1 for cost accounting entities
- Set “Threshold for parallel processing” to 0
- This prevents race conditions during dimension combination creation
Cost Center Table Structure Handling:
The cost center table has specific constraints you must respect:
-
Composite Key Structure:
- Primary key is NOT just CostCenterID
- It’s (CostCenterID + DimensionCombinationRecID)
- The system generates DimensionCombinationRecID based on dimensional attributes
- If you provide the same dimensional attributes twice, same RecID is generated = duplicate key
-
Dimension Combination Logic:
D365 automatically creates dimension combination records. When you import:
CC-1001, AREA-NORTH, DEPT-SALES
The system:
- Creates cost center CC-1001
- Looks up or creates dimension combination for AREA-NORTH + DEPT-SALES
- Links cost center to dimension combination via RecID
- If this combination already exists, reuses the RecID
-
Avoid These Patterns:
- Don’t import cost centers with dimension values in the same entity
- Don’t include derived/calculated dimension combinations from source
- Don’t re-import without clearing dimension combination cache
Source Data Transformation:
Transform your source data to match the required structure:
Source Query for Job 1 (Master Data):
SELECT DISTINCT
CostCenterID,
CostCenterName,
CostCenterType,
IsActive
FROM LegacyERP.CostCenters
Source Query for Job 3 (Dimensions):
SELECT DISTINCT
cc.CostCenterID,
'AREA' as DimensionName,
cc.AreaCode as DimensionValue
FROM LegacyERP.CostCenters cc
WHERE cc.AreaCode IS NOT NULL
UNION
SELECT DISTINCT
cc.CostCenterID,
'DEPARTMENT' as DimensionName,
cc.DepartmentCode as DimensionValue
FROM LegacyERP.CostCenters cc
WHERE cc.DepartmentCode IS NOT NULL
This unpivots dimensions into separate rows, each creating one dimension association.
Execution Sequence:
- Clear target environment (run cleanup script)
- Execute Job 1 - Import 8,500 cost center master records
- Validate: Query CAMCostCenter table, verify 8,500 records present
- Execute Job 2 - Import dimension members (if needed)
- Execute Job 3 - Import dimension associations (likely 15,000-25,000 rows if multiple dimensions per cost center)
- Enable “Skip duplicate records” in Job 3 execution settings
- Validate: Query CAMCostCenterDimensionCombination for expected associations
Error Handling:
If duplicates still occur:
- Check DMF execution logs for the specific duplicate key values
- Query staging table to see if those combinations appear multiple times
- Verify no custom code in CAMCostCenterEntity that generates additional records
- Review data entity field mappings - ensure no many-to-many relationships in single entity
This approach has successfully migrated cost accounting data for implementations with 50,000+ cost centers and complex dimensional hierarchies. The key is separating master data from dimensional relationships and respecting the composite key structure of the cost center table.