SAP Commerce Architect Series — Part 2
Moving beyond items.xml: learning how to think about relationships, lifecycle, scalability, B2B structures, integrations, and maintainability before designing your model.
Introduction
In Part 1 of the SAP Commerce Data Modeling Guide, we explored the foundations of the SAP Commerce type system: ItemTypes, attributes, enums, relations, deployment tables, indexes, and the structure of items.xml.
Those concepts help us understand how SAP Commerce represents data.
But as you gain experience, another question becomes much more important:
How do I know what the right data model should be?
Knowing how to create an ItemType is one skill.
Deciding whether you need that ItemType in the first place is another.
That second skill becomes increasingly important when you start working on larger enterprise implementations.
A model that looks perfectly reasonable with 100 test records may behave very differently with millions of records.
A relationship that feels convenient today may become difficult to maintain after several business enhancements.
An attribute that looks harmless may eventually become part of search, pricing, integrations, reporting, authorization, or batch processing.
That’s why Part 2 is intentionally different from Part 1.
We’re going to spend less time memorizing XML and more time thinking through design decisions.
We’ll take realistic enterprise requirements, walk through them together, challenge the obvious solution, and then look at how we might represent them in SAP Commerce.
The goal isn’t to give you one universal “correct” model.
The goal is to help you develop a repeatable way of thinking about data modeling.
Let’s start with a deceptively simple requirement.
1. Before You Open items.xml, Understand the Business Object
Imagine you’re working on a B2B commerce application.
The business gives you this requirement:
Customers should be able to upload compliance certificates.
At first glance, this sounds simple.
If you’re relatively new to SAP Commerce, your first thought might be:
“I’ll add certificate information to the customer.”
Something like:
Customer ├── certificateNumber ├── certificateExpiryDate └── certificateFile
Technically, we could build this.
But before we decide, let’s forget about SAP Commerce for a few minutes.
Let’s Explore the Requirement Together
As we discuss the requirement with the business, we learn a little more.
A customer may have multiple certificates.
Each certificate has its own expiration date.
A certificate may need to go through an approval process.
When a certificate is replaced, the previous version may need to remain available for audit purposes.
The document itself may be stored as a file, while the certificate metadata needs to be searchable.
In the future, the same certificate information may also need to be exchanged with another enterprise system.
Now our original requirement looks very different.
We’re no longer storing three simple values.
We’re modeling something that has:
- identity,
- ownership,
- status,
- history,
- lifecycle,
- business rules,
- and potentially integration behavior.
That’s a strong indication that we’re dealing with a separate business object.
The First Design May Work — Until the Requirement Changes
Suppose we add certificate-related attributes directly to the customer.
For the first release, everything works.
Then the business asks:
“Can a customer have five certificates?”
Now what?
We could introduce more collections or serialize data into another attribute.
But once we start working around the model rather than allowing the model to represent the business naturally, it’s usually worth revisiting the design.
A cleaner structure may be:
Customer │ │ 1 └────────── * CustomerCertificate │ ├── certificateNumber ├── certificateType ├── expiryDate ├── status ├── uploadedDate └── document → Media
Now every certificate has its own identity and lifecycle.
If tomorrow we introduce approval history, renewal notifications, or external synchronization, the fundamental model does not need to be redesigned.
💡 Design Insight
Many developers begin a requirement by asking:
“Where should I store this information?”
A better question is:
“What business concept am I trying to represent?”
Those questions sound similar, but they often lead to very different designs.
The first focuses on fields.
The second focuses on the domain.
Let’s Think Beyond Today’s Requirement
Imagine the business returns six months later and asks for:
- certificate renewal reminders,
- approval history,
- multiple document versions,
- reporting by certificate type,
- expiration dashboards,
- external system integration.
Would our original three attributes still be a good design?
Probably not.
This does not mean we should predict every possible future requirement.
Overengineering is also a problem.
The goal is to recognize reasonable directions in which the business object may evolve.
⚠️ A Situation I’ve Seen Many Times
A feature begins with two or three new attributes.
Each subsequent enhancement adds another attribute.
Eventually an existing model becomes responsible for information belonging to several different business concepts.
Nothing is technically broken.
But every future enhancement becomes harder.
Often, the real problem isn’t the implementation.
It’s that the business boundaries weren’t identified clearly enough during the original design.
🎯 Key Takeaway
Before creating an ItemType—or adding more attributes to an existing one—understand the lifecycle and responsibility of the data.
If something can independently be created, updated, approved, expired, versioned, searched, or integrated, consider whether it should be represented as its own business object.
2. Choosing the Right Relationship: Start With the Business, Not Cardinality
Once we’ve identified our business objects, the next question is usually:
How should these objects be related?
SAP Commerce allows us to model relationships such as:
- one-to-one,
- one-to-many,
- many-to-many.
Knowing those definitions is easy.
Choosing the correct relationship is where the real thinking begins.
Let’s continue with our certificate example.
A customer can have several certificates.
A certificate belongs to one customer.
Conceptually:
Customer 1 ─────────── * CustomerCertificate
That’s one-to-many.
But don’t stop after identifying cardinality.
Ask how the application will actually use the relationship.
Do we regularly start from a customer and retrieve its certificates?
Probably.
Do we also frequently start from a certificate and need to identify its customer?
Possibly.
Those usage patterns matter.
3. Directional vs Bidirectional Relations
This is an area where unnecessary complexity can easily enter a model.
Developers sometimes create navigation from both sides of a relationship simply because it’s convenient.
Let’s use another example.
Suppose an organization can have multiple shipping profiles.
Conceptually:
B2BUnit │ └────────── * ShippingProfile
Most application flows may start with the B2BUnit and ask:
“Which shipping profiles are available for this organization?”
Navigation in that direction makes sense.
But do we really have an application flow that starts from a shipping profile and needs to navigate back through the organization relationship?
If not, exposing unnecessary navigation may not provide much value.
Think of it as:
B2BUnit ──────────>>>> ShippingProfile
If business logic genuinely needs navigation in both directions:
B2BUnit <──────────>>>> ShippingProfile
then representing both sides may be appropriate.
The important point is not that one style is universally better.
It’s that navigation should exist because the domain needs it, not merely because it is convenient for the developer.
Example Relation
A simplified relation might look like this:
<relation code="CustomerCertificateRelation" localized="false">> <sourceElement qualifier="customer" type="Customer" cardinality="one"/>> <targetElement qualifier="certificates" type="CustomerCertificate" cardinality="many"/>></relation>>
The important part isn’t memorizing the XML.
It’s understanding what the relation represents:
One Customer │ └────── Many CustomerCertificates
Before adding a relation, make sure the business meaning is clear.
💡 Design Insight
When designing a relation, ask two separate questions:
What is the business cardinality?
and
How does the application actually navigate this relationship?
Cardinality describes the business.
Navigation describes how the application uses that business relationship.
Don’t confuse the two.
4. When a Many-to-Many Relation Is Not Enough
Let’s look at a slightly more interesting scenario.
Suppose products can be associated with warehouses.
A product can exist in multiple warehouses.
A warehouse can contain multiple products.
At first glance:
Product * ─────────── * Warehouse
Many-to-many.
Simple.
Then the business adds another requirement.
For every Product-Warehouse combination, we now need:
- sourcing priority,
- active status,
- effective date,
- fulfillment type.
Stop here for a moment.
Where do those attributes belong?
They don’t belong to Product.
They don’t belong to Warehouse.
They belong to the relationship between Product and Warehouse.
That’s an important modeling signal.
Instead of a simple many-to-many relation, we might introduce:
Product │ ▼ProductWarehouseAssignment │ ├── priority ├── active ├── effectiveDate └── fulfillmentType │ ▼Warehouse
The relationship itself has now become a business concept.
💡 Design Insight
When a relationship starts accumulating its own attributes, ask:
Has the relationship itself become a business object?
You may see this pattern in many domains.
For example:
Customer ↔ Product
may evolve into:
CustomerProductAgreement
Or:
Supplier ↔ Product
may evolve into:
SupplierProductAssignment
An explicit intermediate object gives that relationship room to evolve.
⚠️ Common Mistake
Don’t force additional relationship data onto either side merely to avoid creating another model.
If the data describes the association itself, model that association intentionally.
5. Let’s Talk About B2BUnit Modeling
B2B data modeling deserves special attention because enterprise customer structures can become complex very quickly.
A common misunderstanding is:
B2BUnit = Company
Sometimes that may be enough.
But not always.
An enterprise structure might look something like:
Enterprise Organization │ ▼ Sold-To │ ▼ Sales Area │ ▼ Ship-To │ ▼ Users
The exact hierarchy depends entirely on the business.
That’s why we shouldn’t start by forcing the organization into a technical tree.
First understand what each level means.
Let’s Walk Through the Business
Imagine a large industrial distributor.
One enterprise customer has a commercial account.
The same account operates across several regions.
Each region has multiple delivery locations.
Different users may be allowed to place orders only for specific delivery locations.
Pricing may be determined at one organizational level.
Inventory visibility may be controlled at another.
Shipping addresses may belong to the delivery location.
Approval rules may depend on where the user sits within the organization.
Suddenly, “customer” is no longer just one record.
We’re modeling an organization.
Before Designing the Hierarchy
Before deciding how B2BUnits should be structured, understand:
- Which entity represents the commercial customer?
- Which entity receives the shipment?
- Which level determines pricing?
- Which level determines addresses?
- Which level controls user visibility?
- Which level participates in approval?
- Which identifier is sent to an external system?
- Can a user work with multiple organizational units?
- Can the hierarchy change over time?
Only after these answers are clear should you finalize the technical hierarchy.
🏢 Enterprise Insight
One of the most dangerous assumptions in B2B Commerce is that the technical hierarchy automatically equals the business hierarchy.
It doesn’t.
The SAP Commerce model should represent the organization’s business relationships—not force the organization into an arbitrary technical structure.
6. Search Restrictions Belong in the Modeling Conversation
Let’s imagine something unexpected happens.
You create the hierarchy.
The data exists in the database.
An administrator can see all records.
A FlexibleSearch query run with elevated access returns exactly what you expect.
But a customer logs in and cannot see one of their delivery locations.
Where do you start debugging?
Many developers immediately inspect:
Controller ↓Facade ↓Service ↓DAO
But the application may be behaving correctly.
The issue could be visibility.
In B2B implementations, Search Restrictions can determine which records a particular user is allowed to retrieve.
That means structure and visibility should not always be designed independently.
When designing the hierarchy, ask:
Who should be able to see this data?
A technically correct relationship isn’t enough if the visibility model doesn’t match the business.
💡 Design Insight
For important B2B structures, think about three things together:
Structure +Ownership +Visibility
If those three aren’t clear, future access problems become much harder to diagnose.
7. Model the Business Process, Not Just the Upload Screen
Let’s look at another common enterprise requirement.
Users should be able to upload a spreadsheet containing products and quantities.
At first, we might think:
Upload File → Cart
Simple.
But let’s explore what really happens.
The spreadsheet may contain 200 rows.
Some products may not exist.
Some quantities may be invalid.
Some products may not be orderable.
Some lines may succeed while others fail.
The user may need to review errors before continuing.
The business may also want upload history.
Now the flow looks more like:
Spreadsheet │ ▼BulkOrderUpload │ ▼BulkOrderEntry │ ▼Validation │ ├──────── Invalid Entries │ ▼Validated Entries │ ▼Cart │ ▼Order
Now we’ve discovered something important.
The upload is not simply a file.
It’s a business process with state.
Possible Model
BulkOrderUpload ├── uploadedBy ├── uploadedTime ├── status ├── sourceFile └── entries │ └── BulkOrderEntry ├── productCode ├── quantity ├── status └── validationMessage
This gives us the ability to:
- track upload history,
- identify failed lines,
- retry processing,
- show validation messages,
- report on failure patterns,
- troubleshoot production issues.
⚠️ Common Mistake
Don’t store structured business information as JSON simply because it’s easy to implement.
JSON can absolutely be appropriate for some use cases.
But if the business regularly needs to:
- search,
- filter,
- report,
- relate,
- validate,
- update individual records,
then pause and consider whether the data deserves proper domain modeling.
🎯 Key Takeaway
Model the business process, not just the UI element that starts it.
An upload button may look simple.
The business workflow behind that button may not be.
8. Files and Business Metadata Are Different Things
Let’s look at document management.
Suppose an order can have several documents:
- invoice,
- compliance document,
- warranty document,
- delivery document.
We could associate Media records directly with the order.
But later, the business needs:
- document number,
- document type,
- status,
- issue date,
- expiration date,
- source system,
- visibility rules.
Those fields describe the business document.
They don’t simply describe a file.
A cleaner design may be:
Order │ └────────── * OrderDocument │ ├── documentNumber ├── documentType ├── status ├── issueDate ├── sourceSystem └── media │ ▼ Media
Think of the difference this way:
Mediaanswers: Where is the file?
OrderDocumentanswers: What does this file mean to the business?
That distinction becomes increasingly valuable as an application grows.
💡 Design Insight
Don’t make a storage mechanism represent a business concept.
A PDF is a file.
An invoice is a business document.
Those are related concepts—but they are not the same thing.
9. Where Should the ItemType Live?
Now let’s move from domain design into extension architecture.
Imagine the solution contains:
customcorecustomfacadescustomstorefrontcustomintegrationcustombackoffice
A developer is implementing a storefront feature and creates a new ItemType inside the storefront extension because that’s where the current development is happening.
The feature works.
A few months later, the integration layer needs the same model.
Now we have a dependency problem.
The integration extension shouldn’t need to depend on the storefront simply to access a shared business model.
A cleaner architecture looks more like:
customcore
│
Domain Models
│
┌────────────┼────────────┐
▼ ▼ ▼
customfacades customintegration custombackoffice
│
▼
customstorefront
Shared business concepts generally belong in an appropriate lower-level/core extension so that higher-level components can depend on them cleanly.
💡 Design Insight
Ask:
“Who owns this business concept?”
not:
“Which feature am I currently coding?”
Where the feature appears in the UI and where its business model belongs are not necessarily the same thing.
⚠️ Common Mistake
Avoid placing reusable models inside an extension simply because that extension happened to introduce the original requirement.
That can create unnecessary dependencies later.
10. Data Modeling and Performance Are Connected
Performance problems usually appear long after the original feature was developed.
That’s why they’re easy to miss during design.
Imagine a B2BUnit eventually has tens of thousands of related records.
A developer writes code that effectively navigates a very large collection.
It worked perfectly during development.
Development had 20 records.
Production has 50,000.
Those are very different environments.
Before adding a collection or relation, ask:
How large can this become?
Do we really need to navigate the entire collection?
Would querying a filtered subset be more appropriate?
Will this data be displayed with pagination?
Which attributes will commonly appear in search conditions?
These are data modeling questions, not just performance-tuning questions.
🏢 Enterprise Insight
One of the biggest differences between development and production isn’t the code.
It’s the data volume.
Always mentally test your design with realistic production-sized data.
11. Think About Indexes From the Access Pattern
Suppose we have:
CustomerCertificate
with fields such as:
customercertificateNumberstatusexpiryDate
Now imagine several application flows.
A scheduled process asks:
Find approved certificates expiring within the next 30 days.
Customer service asks:
Find a certificate using its certificate number.
The customer account page asks:
Find certificates belonging to this customer.
These access patterns should influence the indexing discussion.
Indexes shouldn’t be added randomly.
Too few indexes can lead to expensive queries.
Too many indexes also carry a cost during writes and maintenance.
The best starting point is understanding how the data will actually be queried.
✅ Best Practice
Before finalizing an important model, write down several expected access patterns.
For example:
1. Find certificates by customer.2. Find certificate by external number.3. Find certificates by status.4. Find certificates expiring before a given date.
Then ask:
Does our model support these queries naturally?
Which filters are frequent?
Which ones are selective?
Do we need a combined index for a frequently used query pattern?
This simple exercise often reveals design problems early.
12. FlexibleSearch Can Reveal Modeling Problems
Here’s another technique I like.
Before approving a data model, imagine the FlexibleSearch queries developers will need to write.
Suppose the business asks:
“Show all approved certificates for this customer that expire within the next 30 days.”
With a well-structured model, the query conceptually remains straightforward:
SELECT {c.pk}FROM {CustomerCertificate AS c}WHERE {c.customer} = ?customer AND {c.status} = ?status AND {c.expiryDate} <= ?expiryDate
That’s easy to understand.
Now imagine certificate data was stored inside a JSON attribute on the Customer.
How would we efficiently:
- filter by status,
- search by certificate number,
- find expiring certificates,
- create reports,
- build scheduled jobs?
The difficulty of those operations tells us something about the model.
💡 Design Insight
Before approving an important ItemType, try writing three or four realistic queries against it.
If simple business questions require unusually complicated retrieval logic, revisit the model.
Sometimes the query isn’t the problem.
Sometimes the model is.
13. Designing Models for Integrations
SAP Commerce rarely operates alone.
Enterprise platforms commonly communicate with:
- ERP systems,
- CRM platforms,
- payment services,
- middleware,
- document management systems,
- warehouse systems,
- external APIs.
That’s why integration requirements should influence modeling decisions.
Let’s return to our certificate example.
If certificate information is synchronized with another system, we may need information such as:
externalIdsourceSystemsyncStatuslastSyncTime
Depending on the use case, operational information may also be required elsewhere, such as integration/audit records rather than directly on the business object.
The exact design depends on how important synchronization history is and how complex the integration becomes.
The key point is that integration state should be designed intentionally.
Let’s Think Beyond the Happy Path
Everyone designs for:
Commerce → External System → Success
But production systems also experience:
Commerce │ ▼Integration │ ├── Timeout ├── Validation Error ├── External System Unavailable └── Partial Failure
When something fails at 2:00 AM, what information will the support team need?
Can they identify:
- which record failed,
- which external identifier was used,
- when synchronization was attempted,
- whether the operation can be retried?
Those questions influence architecture.
🏢 Enterprise Insight
Production support is part of architecture.
A design isn’t complete simply because the successful flow works.
Think about how the system will explain itself when something goes wrong.
14. Don’t Put Everything Into One ItemType
Let’s imagine an enterprise account model slowly grows over several years.
It starts with:
Account ├── id └── name
Then new requirements arrive:
Account ├── pricingConfiguration ├── shippingConfiguration ├── approvalConfiguration ├── complianceInformation ├── documentInformation ├── integrationStatus ├── notificationPreferences └── ..
Eventually, one model becomes responsible for too many business areas.
This creates coupling.
A change in compliance affects the account model.
A change in shipping affects the same model.
Integration changes touch it again.
At some point, it becomes difficult to understand where one responsibility ends and another begins.
Let’s Challenge the Model
Could some of those concepts have their own lifecycle?
For example:
Account │ ├──── ShippingProfile │ ├──── ComplianceProfile │ ├──── NotificationPreference │ └──── AccountDocument
Now each concept has clearer ownership.
That doesn’t mean every attribute deserves a separate ItemType.
Remember:
Too little modeling creates oversized objects.
But:
Too much modeling creates unnecessary complexity.
Good design sits somewhere between those extremes.
💡 Design Insight
Don’t ask:
“Can this be another ItemType?”
Ask:
“Does separating this concept make the domain clearer?”
That’s a much better design test.
15. Avoid Designing Only for the UI
Here’s another pattern worth recognizing.
Imagine the UI has a form:
Customer InformationShipping InformationPreferencesCompliance Information
It can be tempting to create exactly four ItemTypes because the page has four sections.
But screens aren’t domains.
Tomorrow UX may combine those sections.
Next year the application may expose the same information through OCC APIs.
Another application may not have a UI at all.
The domain should survive those changes.
💡 Design Insight
UI structure answers:
How should the user interact with the information?
Data modeling answers:
What does the information mean to the business?
Those are different questions.
Design the domain first.
Let the UI consume it.
16. Multi-Extension Model Sharing
As projects become larger, several custom extensions may need access to the same domain model.
For example:
customcore
│
CustomerCertificateModel
│
┌────────────────┼────────────────┐
▼ ▼ ▼
integration backoffice facades
│
▼
storefront
The shared domain belongs at a layer where all legitimate consumers can use it without introducing unnatural dependencies.
This becomes especially important when multiple teams work on the same application.
Without discipline, extension dependencies slowly become:
Extension A → Extension BExtension B → Extension CExtension C → Extension A
Now everything depends on everything.
That’s difficult to maintain.
✅ Best Practice
For every new shared model, ask:
Who owns it?
Who consumes it?
Which extension should provide it?
Will this dependency still make sense two years from now?
Dependencies should communicate architectural intent.
17. Realistic Data Volume Changes Design Decisions
Let’s imagine we’re designing a customer-specific product configuration.
During development:
Customers: 100Products: 500Mappings: 5,000
Everything performs well.
Now imagine production:
Customers: 500,000Products: 5,000,000Potential combinations: enormous
Suddenly, a naive Customer-to-Product relation deserves another look.
Questions change.
Do we really store every possible combination?
Can configuration be represented at a higher organizational level?
Can rules replace explicit rows?
Can external pricing remain external rather than being duplicated?
Can records be partitioned conceptually by contract or account?
This is why scale must be considered during modeling.
🏢 Enterprise Insight
A technically valid relationship is not automatically a scalable relationship.
Always ask:
How many records can this design create?
Cardinality is not only about one and many.
It’s also about understanding what many might actually mean in production.
18. Common Data Modeling Mistakes
Let’s bring several of these lessons together.
Mistake 1 — Creating ItemTypes Too Quickly
Requirement arrives.
Developer opens items.xml.
Instead, understand the business lifecycle first.
Mistake 2 — Adding Everything to Existing Models
Avoid turning Customer, Product, Order, or B2BUnit into containers for unrelated responsibilities.
Mistake 3 — Modeling Based Only on Today’s Screen
Screens change.
Business concepts tend to remain more stable.
Mistake 4 — Using Many-to-Many When the Relationship Has Meaning
If the association needs attributes, consider modeling the association explicitly.
Mistake 5 — Ignoring Expected Data Volume
Always imagine your model with production-scale data.
Mistake 6 — Ignoring Query Patterns
Think about FlexibleSearch and reporting before the database contains millions of records.
Mistake 7 — Ignoring Visibility
Especially in B2B implementations, structure, ownership, and authorization should be considered together.
Mistake 8 — Putting Models in the Wrong Extension
Domain ownership should determine placement—not whichever feature happened to introduce the requirement.
Mistake 9 — Overengineering
Not every field needs an ItemType.
Not every relation needs an intermediate object.
Not every future possibility needs to be modeled today.
Architecture is about thoughtful trade-offs.
19. My Data Modeling Review Checklist
Before finalizing a significant SAP Commerce model, I like to work through questions like these.
Business
- What business concept are we representing?
- Does it have its own lifecycle?
- Who owns the data?
- Can it exist independently?
- Can there be multiple records?
- Can it change status?
Relationships
- What is the real cardinality?
- Which direction does the application navigate?
- Does the relationship itself carry business information?
Scale
- How many records could exist?
- Could a collection become extremely large?
- Will queries require pagination?
- Which attributes will be used frequently for searching?
Integration
- Does another system own or consume this information?
- Is an external identifier required?
- Do we need synchronization status?
- How will failures be diagnosed?
Security
- Who can see the data?
- Who can update it?
- Do Search Restrictions or organizational boundaries affect access?
Architecture
- Which extension owns the model?
- Who consumes it?
- Are we creating unnecessary dependencies?
- Will another team understand this structure six months from now?
You won’t always need every question.
The important part is developing the habit of asking them.
☕ Before You Move On
Think about one feature you’ve implemented recently.
Maybe it involved:
- customer information,
- product configuration,
- order metadata,
- documents,
- B2B hierarchy,
- integration data.
Now ask yourself:
Did I model the business object—or just the immediate requirement?
Did I think about its lifecycle?
Did I consider production data volume?
Would I design it differently today?
Every experienced developer has designs they would approach differently after gaining more knowledge.
That’s part of becoming a better engineer.
The goal isn’t to design everything perfectly the first time.
The goal is to improve the quality of the questions we ask before implementation begins.
Final Thoughts
The most important lesson from Part 2 is this:
SAP Commerce data modeling is not primarily about writing
items.xml. It is about understanding the business well enough to represent it cleanly in software.
As a junior developer, you naturally focus on:
“How do I implement this?”
As you gain experience, another question becomes equally important:
“Why should we implement it this way?”
And eventually:
“What happens to this design when the business, data volume, and system integrations grow?”
That’s the transition from implementation thinking to enterprise design thinking.
You don’t need an architect title to start thinking this way.
You simply need to develop the habit of slowing down before coding, understanding the domain, challenging the first solution, and considering how the model will behave beyond today’s requirement.
That’s a skill you can practice on every feature you build.
Frequently Asked Questions
Should every business object become a new ItemType?
No.
Creating too many ItemTypes can introduce unnecessary complexity.
A separate ItemType becomes more valuable when the concept has its own lifecycle, identity, relationships, status, ownership, or independent behavior.
Should every relation be bidirectional?
No.
Model navigation based on real application requirements.
Don’t expose additional navigation simply because it may be convenient.
When should I replace a many-to-many relation with an intermediate ItemType?
When the relationship itself begins carrying business data.
For example, if a Product-Warehouse association needs priority, status, or effective dates, the association may deserve its own model.
Should I add indexes to every searchable attribute?
No.
Indexes should be driven by realistic query patterns, selectivity, expected data volume, and database behavior.
Adding indexes without understanding the access pattern can also create unnecessary overhead.
Should integration status always be stored on the business model?
Not necessarily.
Simple integrations may justify a small amount of operational information on the model.
More complex integrations may benefit from separate integration history or audit models.
Choose based on lifecycle, troubleshooting requirements, and ownership.
Should B2BUnit always represent a Sold-To or company?
No.
B2B organizational structures vary significantly across implementations.
Understand the business hierarchy first and then decide how SAP Commerce should represent it.
🎯 Key Takeaways
If you remember only a few things from this article, remember these:
1. Understand the business before opening items.xml.
2. Model business objects, not screens.
3. Understand lifecycle before deciding between attributes and ItemTypes.
4. Don’t make relationships more complex than the domain requires.
5. If a relationship has its own business data, consider modeling it explicitly.
6. In B2B systems, structure, ownership, and visibility should be considered together.
7. Think about query patterns and data volume during design—not after production becomes slow.
8. Shared business models should live in the appropriate architectural layer.
9. Design for reasonable evolution without overengineering.
10. Always understand the reason behind a modeling decision.
What’s Coming in Part 3?
In Part 3 of the SAP Commerce Architect Series, we’ll move from modeling into data access:
SAP Commerce FlexibleSearch Deep Dive
We’ll explore:
- how FlexibleSearch really works,
- joins,
- parameters,
- pagination,
- relation queries,
EXISTSand subqueries,- Search Restrictions,
- common performance mistakes,
- indexes,
- query design,
- troubleshooting slow queries,
- and practical enterprise scenarios.
And just like this article, we won’t stop at syntax.
We’ll understand why one query performs better than another and how experienced developers approach data retrieval at enterprise scale.
Part of the SAP Commerce Architect Series
Practical SAP Commerce learning focused not only on how the platform works, but on how to think through enterprise design decisions.
One lesson at a time.

Leave a comment