A note from 2026: This article was published in 2018, when SAP Commerce Cloud was still widely referred to as SAP Hybris Commerce. The product name, documentation URLs, and some platform internals have changed since then; validate table structures and version-specific behavior against your current SAP Commerce Cloud release.

Database structure

The purpose of this document is to shed light on the internal data structures used by SAP Hybris Commerce. I explain system tables and attributes, their purpose, and their meaning.

You know that SAP Hybris Commerce has a powerful type system built on top of the database layer. It means that you can’t, and are not recommended to, write to the database directly. Direct reads are also not recommended. So, basically, the information about specific attributes and table names is not used by developers directly.

However, understanding the internal structure is very useful in troubleshooting and low-level data analysis. For example, direct access to the database may show that your system has many unused items, and that affects performance. Analyzing the data is also extremely helpful with data integrity issues.

Looking at the underlying data model, you will understand the processes better. You will see that SAP Hybris Commerce is not a black box with hidden algorithms and logic under the hood.

Summary: Don’t write to the database directly in Hybris. Use the Hybris data access APIs in all situations when you need to modify things. There are no exceptions. Otherwise, you will definitely have issues with the caching subsystem. The explanations below are important for troubleshooting and early detection of data issues.

Hybris Database Internals

Creating Tables

Hybris creates tables during the initialization and update processes. It loads old-style ([-.]advanced-deployments.xml) and new-style data model definitions (*-items.xml).

Hybris generates the database schema using HybrisSchemaGenerator.initialize(). The schema is created as a set of SQL files in the temporary directory using Apache DDLUtils SQLBuilder. The generator uses the information loaded from the XML model definitions. Hybris creates three files:

The generated files are executed as a batch using Spring Core JDBC.

There is a table prefix configured for the instance. By default, it is empty.

Table Types

Item Type Tables

The major part of the list of Hybris database tables is item type tables. These tables are created automatically from *-items.xml during the system init or update process.

Their names are specified in the deployment tag, so the database tables can have any name chosen by the developer.

Actually, in this process, some of the other tables are created or updated too. For example, localized values tables are created if you have at least one localized attribute. Generic audit tables are created for all item type tables automatically; the feature is available in 6.6+.

Each item type table has at least the following columns:

Localized Values Tables

If the table contains localized properties, with values in different languages, these values are stored separately from the main item type table. The table with such data has the suffix lp. For example, productslp has the following attributes:

Generic Audit Tables

Their names are constructed using the item table name, code, and the suffix sn. For example, for Products, the name of the change history table will be products1sn, where 1 is a type code of Product and sn is a fixed suffix. For tables with long names, the name will be truncated. For example, for the table products4restriction, the change history table will have the name products4restri1081sn.

Not all changes are saved. You need to activate this feature for a particular type. Of course, it will affect performance, but you will be able to track changes. So the set of participating types depends on a particular project and its requirements and constraints.

It has been activated out of the box for the following types: AbstractContactInfo, Address, B2bunit, BaseSite, Btgsegment, Btgsegmentresult, Cart, CartEntry, City, Comment, Consent, ConsentTemplate, Country, CsAgentGroup, CsTicket, Currency, Customerreview, CxSegment, CxUsertosegment, District, Employee, Language, Order, Orderentry, Partneraddress, Paymentinfo, Paymentmode, Principalgrouprelation, Product, Quote, Quoteentry, Region, SapB2bdocument, SapOrder, Title, Unit, User, Usergroup, UserPasswordChangeAudit.

Read more about the Generic Audit feature:
https://help.hybris.com/6.7.0/hcd/3e2b8491449d43b391eb1ce9c73cbb7f.html

The structure of the change history tables:

A relation table, for many-to-many relation types, has the structure above plus additional columns:

The tables are created for all types. For inactive auditing, they will be empty.

For example, if you add a new language, the system will add the following record:

Payload before is JSON:

Payload before JSON screenshot

Payload after contains the same, plus a new item.

Property Tables

Property tables are specified for item types in *-items.xml as part of the deployment tag, in the propertytable attribute.

System Tables

Props Tables

Props tables are a little special, as all attributes that you specify in the items.xml file with the modifier dontOptimize="true" will go there, with their values stored as blobs. There is not much information about it; it is mentioned in the reference here: https://wiki.hybris.com/display/release5/items.xml+Element+Reference#items.xmlElementReference-ComplexType:modifiersType.

Basically, if you set the dontOptimize modifier, the object will be stored in this props table, making it more expensive to search by, but releasing the original object from what is expected to be a heavy column in the database.

Typically, you would want to add attributes to this table when they are too big and you would never want to search by this attribute, for instance the full HMC XML text, or comments that could be added to the items.

Anyway, it is not a very good practice to store attributes in this table, as there are cases where it can grow too much and have a very bad impact on performance. It is better to specify the type of the database you are going to be working on, as explained here.

ACL Entries: Table aclentries

Purpose: Access Control Lists, or Permission-User-Item.

Defined by core-advanced-deployment.xml.

Used by JALO AccessManager. The User/Object permissions are stored here.

Type System Records

Structure

The type system is represented by the following set of tables:

Common Attributes

This set of attributes is used in the following tables:

Attributes and their meaning:

Atomic Types: Table Atomictypes

The following atomic types are created by default with the Hybris Accelerator:

Atomic types table

Collection Types: Table collectiontypes

There are about 500 collection types in SAP Hybris Accelerator.

Composed Types: Table composedtypes

There are about 1100 composed types in SAP Hybris Accelerator, including:

Map Types: Table maptypes

Localized Properties: Tables maptypeslp, composedtypeslp, atomictypeslp, collectiontypeslp
These tables contain information about item type properties in different languages.

Attribute Descriptors: Table attributedescriptors

Attribute descriptors contain information about type attributes.

There is also a table for localized properties:

Other Tables

Common Attributes

All objects below contain a fixed set of attributes, namely:

Config Items: Table configitems

Enumeration Values: Table enumerationvalues

GenericItems

This table contains the objects of the GenericItem type.

The following attributes are defined by workflow-items.xml, in WorkflowActionTemplateDecisionsTemplateRelation and WorkflowActionDecisionsRelation:

The following attributes are defined by the AbstractAdvancedSavedQuerySearchParameter and TypedAdvancedSavedQuerySearchParameter definitions in advancedsavedquery-items.xml:

There is also a table for localized properties:

gentestitems

This table contains the instances of GenericTestItem used in the test classes.

junit_numberseries

NumberSeries is used for JUnit to test a unique PK pool. The structure is the same as in NumberSeries; see below.

links

This table is used for the objects of the ExtensibleItem type.

This table is used by LinkManager for non-root relations.

mediaprops

See the information about props tables above.

metainformations

Hybris saves tenant information here.

numberseries

This table is used by the NumberSeries API for generating unique keys. From the service layer, it is used by PersistentKeyGenerator. For example, it is used for orders, comments, media, cronjobs, processes, workflows, and workflow actions. See the NumberSeries class for the details. It is used by various components to generate unique identifiers.

pgrels and orderdiscrels

pgrels is used for the objects of the PrincipalGroupRelation type, which extends Link.

orderdiscrels is used for the objects of the OrderDiscountRelation type, which extends Link.

Both have the following structure:

As far as I know, OrderDiscountRelation is not used anymore. It was replaced by DiscountModel.

searchrestrictions

This table is used for the objects of the SearchRestrictions type, which extends Link.

There is also a table for localized properties:

testitem

TestItem is used in unit tests. There are fields of different types.

ydeployments

This table contains information about type deployments: what table corresponds to what type, and what configuration options should be taken into account.

Special Attributes

hjmpTS

This attribute contains a number that is used for concurrent writes management. There is some extra information relevant to the topic that you may find useful:

It’s meant to support optimistic locking in the same way as a persistence layer like Hibernate does with a @Version annotation.

Basically, when you select a row from the database, that returns the current version. When the row is updated, the version column is incremented. When you update the row, you use a WHERE clause on the query to match the version that you selected. If the update doesn’t modify any rows, then you know something else has updated the row, and version, in the meantime.

hjmp.throw.concurrent.modification.exceptions (default false) is a config parameter that either enables or disables checking that, upon update, an item row must have the same version that was read when fetching the HJMP entity object.

This means setting the hjmp.throw.concurrent.modification.exceptions parameter to true in properties activates optimistic locking and, of course, increases the risk of seeing optimistic concurrency exceptions, such as HJMPException(PK was modified concurrently – expected version …), which will force a transaction rollback.

P.S.: If you don’t enable optimistic locking, only the dirty attributes will be written, and the final result will be a merge.

(source)