Mappers
Mappers
Mapper definitions that transform source data fields to Pricefx format.
When to Use
|
Mapper type |
Use when |
API method |
|---|---|---|
|
|
Bulk load / replace data |
|
|
|
Upsert (insert or update by key) |
|
|
|
Nested/hierarchical data |
Multi-level operations |
|
Attribute |
Details |
|---|---|
|
Purpose |
Define how source fields map to Pricefx fields (rename, transform, convert types) |
|
Format |
XML — |
|
Naming |
By entity or function: |
|
Loaded by |
Spring context at startup — registered as beans by mapper ID |
Mapper Types
|
Element |
Description |
|---|---|
|
|
Used with |
|
|
Used with |
|
|
For nested data structures where one source record produces multiple levels of output. |
Expression Types
|
Expression type |
Attribute |
Description |
|---|---|---|
|
|
|
Direct field copy from source map |
|
|
|
Camel Simple expression ( |
|
|
|
Fixed literal value |
|
|
|
Groovy script — access source via |
Key rules:
-
bodyis cheapest — use it for simple field rename / copy -
groovyis most powerful — required for conditionals, calculations, multi-field logic -
constantfor table names, fixed flags, enums
Attributes Reference
|
Attribute |
On |
Description |
|---|---|---|
|
|
mapper |
Unique mapper bean ID. Must match file name (e.g., |
|
|
property |
Source expression — meaning depends on |
|
|
property |
Target Pricefx field name |
|
|
property |
Expression type: |
|
|
property |
Built-in converter name, e.g., |
|
|
property |
Custom converter Spring bean name (rare — usually want |
|
|
property |
If |
|
|
property |
Used by converter when the source value is null or empty |
|
|
property |
If |
|
|
property |
Locale for number/date converters (e.g., |
Built-in Converter Expressions
|
converterExpression |
Input → Output |
Notes |
|---|---|---|
|
|
String → BigDecimal |
Respects |
|
|
String → Integer |
|
|
|
String → Long |
|
|
|
String → Date |
Uses format from |
|
|
String → DateTime |
Uses format from |
|
|
Date → String |
Uses format from |
|
|
String → Boolean |
|
|
|
Boolean → Integer |
true→1, false→0 |
|
|
Integer → Boolean |
1→true, 0→false |
Examples
loadMapper — Products from CSV
<mappers>
<loadMapper id="import-products.mapper">
<property expression="sku" out="sku" type="body"/>
<property expression="label" out="label" type="body"/>
<property expression="unitOfMeasure" out="unitOfMeasure" type="body"/>
<property expression="currency" out="currency" type="body"/>
<property expression="listPrice" out="attribute1" type="body"
converterExpression="stringToDecimal" defaultValue="0"/>
</loadMapper>
</mappers>
integrateMapper — Customer upsert
<mappers>
<integrateMapper id="upsert-customers.mapper">
<businessKey>
<property expression="customerId" out="customerId" type="body"/>
</businessKey>
<property expression="customerId" out="customerId" type="body"/>
<property expression="customerName" out="label" type="body"/>
<property expression="country" out="attribute1" type="body"/>
<property expression="region" out="attribute2" type="body"/>
</integrateMapper>
</mappers>
PX (Product Extension) mapper — table name via constant
<mappers>
<loadMapper id="import-px.mapper">
<constant expression="Costs" out="name"/>
<property expression="sku" out="sku" type="body"/>
<property expression="cost" out="attribute1" type="body"
converterExpression="stringToDecimal" defaultValue="0"/>
<property expression="vendor" out="attribute2" type="body"/>
</loadMapper>
</mappers>
Groovy expression — conditional mapping
<mappers>
<loadMapper id="import-with-logic.mapper">
<property expression="sku" out="sku" type="body"/>
<property type="groovy" out="attribute1"
expression="body['status'] == 'ACTIVE' ? body['price'] : 0"/>
<property type="groovy" out="label"
expression="(body['firstName'] ?: '') + ' ' + (body['lastName'] ?: '')"/>
</loadMapper>
</mappers>
Converter Best Practices
Use converterExpression for built-in converters
<!-- CORRECT — built-in converter -->
<property expression="price" out="attribute1" type="body"
converterExpression="stringToDecimal" defaultValue="0"/>
<!-- WRONG — 'converter' is for custom Spring beans -->
<property expression="price" out="attribute1" type="body"
converter="stringToDecimal"/>
Locale-aware number parsing
When source data uses non-US number formats:
<!-- German format: 1.234,56 → 1234.56 -->
<property expression="price" out="attribute1" type="body"
converterExpression="stringToDecimal" locale="de_DE"/>
Default values for nullable numbers
<property expression="discount" out="attribute3" type="body"
converterExpression="stringToDecimal" defaultValue="0"/>
Without defaultValue, a null or empty string converts to null in the target. With defaultValue="0", it converts to BigDecimal.ZERO.
Error handling in conversions
<!-- Skip bad records instead of failing -->
<property expression="quantity" out="attribute2" type="body"
converterExpression="stringToInteger" ignoreError="true"/>
Attribute Value Truncation
When loading data into extension tables (PX, CX, SX), string attribute values may be automatically truncated to prevent Pricefx API errors caused by values exceeding the column size limit.
How It Works
Pricefx extension tables have a fixed database column size for each attribute (typically 255 characters). However, when an extension table has many attributes, the available column size per attribute decreases. The truncation feature dynamically adjusts the maximum allowed string length based on the actual number of attributes configured in the extension table.
The decision logic:
-
IM fetches the extension table metadata from Pricefx (e.g.,
configurationmanager.get/productextension) to determine the number of attributes (numberOfAttributes). -
If
numberOfAttributes >= threshold→ values are truncated tomax.sizecharacters. -
If
numberOfAttributes < threshold→ values are truncated to the standard 255 character limit.
Configuration
|
Property |
Default |
Description |
|---|---|---|
|
|
|
Maximum string length when the extension table has many attributes (at or above the threshold) |
|
|
|
Number of attributes at which the reduced |
|
|
|
Maximum size for JLTV/JLTV2 extended attribute values |
Where <TYPE> is one of: PX, CX, SX.
Default values:
integration.mappers.PX.attributes.truncate.max.size=70
integration.mappers.PX.attributes.truncate.threshold=50
integration.mappers.CX.attributes.truncate.max.size=70
integration.mappers.CX.attributes.truncate.threshold=50
integration.mappers.SX.attributes.truncate.max.size=70
integration.mappers.SX.attributes.truncate.threshold=50
Example
Consider a PX table called Costs with numberOfAttributes=60 (threshold is 50):
-
Since 60 >= 50, the
max.sizeof 70 applies -
Any string attribute value longer than 70 characters is silently truncated to 70 characters via
substring(0, 70)
If the same table had only 30 attributes:
-
Since 30 < 50, the standard 255 character limit applies
Important Notes
-
Truncation applies only to string values. Numbers, booleans, and nulls are not affected.
-
Truncation is a simple
substring(0, maxLength)— no ellipsis or warning is added. -
The extension metadata is cached and refreshed every 10 minutes (configurable via
integration.schedulers.mapper-truncate.cache.ms). -
Standard object types (P, C, SL) always use the 255 character limit — these properties have no effect on them.
-
Applies to
loaddata,integrate, andsaveoperations.
Common Pitfalls
-
Mapper IDs must be unique and match the
mapper=parameter in route URIs -
Each file must have the
<mappers>wrapper element around the mapper definition — do NOT use<beans>,<beans:beans>, or XML declarations -
Use
groovyexpressions for complex transformations,bodyfor simple field mapping -
Built-in type converters (e.g.,
stringToDecimal) must use theconverterExpressionattribute, notconverter. Theconverterattribute is only for custom Spring bean references. -
One mapper per file — do not put multiple mappers in a single file
See Also
-
Routes — Mappers are referenced in routes via
mapper=parameter -
Filters — Filters select data, mappers transform it
-
Converters — Type converters used in mapper expressions
-
pfx-api Component — loaddata and integrate methods use mappers