
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:
- DropDDL — with DropTable statements
- DDL — with CREATE statements for tables and indexes
- DML — with INSERT/UPDATE statements
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
- Localized values tables
- Generic Audit tables
- Property tables
- System tables
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:
hjmpTS. Version (bigint). See the section “HJMPTS”. It is incremented each time either the item table, the*propstable, or theACLEntrytable is changed for a specific item. Example:3createdTS. Created time (datetime). Example:2017-07-07 18:22:49.000000modifiedTS. Modified time (datetime). Example:2017-07-07 18:33:26.000000TypePkString. Reference to a type (*types.pk). See the section “PKs”. Example:8796093087826OwnerPkString. Supposed to be a reference to a type, but it is null. Possibly deprecated.PK. Unique identifier. See the section “PKs”. Example:8796093055058sealedaCLTS. Obsolete by now. It used to be for optimistic locking covering theACLEntrytable. This now relies solely on thehjmpTScolumn.propTS. Obsolete by now. It used to be for optimistic locking covering the*PROPStables. This now relies solely on thehjmpTScolumn.
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:
p_namep_descriptionp_manufactureretypedescriptionp_segmentp_articlestatusp_summaryp_stylep_sizep_color
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:
ID. Unique autoincrement ID.ITEMPK. The Type Instance PK. For products, it is the PK of the particular product.ITEMTYPEPK. The Type PK. For Products, it is a PK from*types.timestamp. Change timestamp.currenttimestamp. Audit Record Timestamp.changinguser. Who changed the item. It is NOT a PK of the user; it is a string, the user login, because the user record can be removed.context. Additional context, in JSON.payloadbefore. The whole business payload of the audited type before a persistence operation, in JSON.payloadafter. The whole business payload of the audited type after a persistence operation, in JSON.operationtype.0— deletion,1— creation,2— modification.
A relation table, for many-to-many relation types, has the structure above plus additional columns:
sourcePK. Source Item PK.targetPK. Target Item PK.languagePK. Language PK.
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:
timestampandcurrenttimestampwill represent the date and time of a change.itempkanditemtypepkwill contain the 13-digit PKs of the language item added and its type,Language.changinguser— your current Backoffice user, such asadmin.operationtype=1, which means “creation”.payloadbeforeandpayloadafter— see below.
Payload before is JSON:

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.
addresspropsquoteentrypropsorderentrypropstypesystempropsusergrouppropsuserpropsquotepropsorderpropsmediapropsproductprops
System Tables
aclentries- Types:
atomictypescollectiontypescomposedtypesmaptypes
attributedescriptorsconfigitemsenumerationvaluesgenericitemsgentestitemsjunit_numberserieslinksmetainformationsnumberseriesorderdiscrelspgrelspropssearchrestrictionsydeploymentstasks_aux_queuetasks_aux_schedulertasks_aux_workerstestitem
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.
addresspropsmediapropsorderentrypropsorderpropsproductpropspropsquoteentrypropsquotepropstypesystempropsusergrouppropsuserprops
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.
ID. Version. See the section “HJMPTS”.ITEMPK. Reference to UserRight Model.negative. Stands for negative permissions.principalPK. Reference to Principal Model.itemPK. Reference to Item Model.
Type System Records
Structure
The type system is represented by the following set of tables:
AtomicTypesComposedTypesMapTypesCollectionTypesEnumerationValuesAttributeDescriptorsPropsMapyDeploymentsCountry
Common Attributes
This set of attributes is used in the following tables:
AtomictypesCollectiontypesCommenttypesComposedtypesMapTypes
Attributes and their meaning:
hjmpTS. Version (bigint). See the section “HJMPTS”. It is incremented each time either the item table, the*propstable, or theACLEntrytable is changed for a specific item. Example:3createdTS. Created time (datetime). Example:2017-07-07 18:22:49.000000modifiedTS. Modified time (datetime). Example:2017-07-07 18:33:26.000000TypePkString. Reference to a type (*types.pk). See the section “PKs”. Example:8796093087826OwnerPkString. Supposed to be a reference to a type, but it is null. Possibly deprecated.PK. Unique identifier. See the section “PKs”. Example:8796093055058p_extensionname. Name of the extension, as a string. Example:coreorcockpitp_autocreate. Create a database table/model or not, as a flag. Example:1p_generate. Generate Jalo classes for the model or not, as a flag. Example:0internalCode. String representation of the Item name. Examples:Item,ComposedType,Media,UserRightfromcore-advanced-deployment.xml.p_defaultvalue. Default value. Example:0.aCLTS. Obsolete by now. It used to be for optimistic locking covering theACLEntrytable. This now relies solely on thehjmpTScolumn.propTS. Obsolete by now. It used to be for optimistic locking covering the*PROPStables. This now relies solely on thehjmpTScolumn.
Atomic Types: Table Atomictypes
- All common attributes +
InheritancePathString. Comma-separated list of PKs that are parents to the item. Example:,8796093055058,8796094431314,8796094464082,JavaClassName. Java class name. Example:de.hybris.platform.jalo.media.MediaContainerfrom core-advanced-deployment.xml.SuperTypePK. Supertype PK. Example:8796094496850InternalCodeLowerCase. Example:java.lang.Longfrom core-advanced-deployment.xml.
The following atomic types are created by default with the Hybris Accelerator:

Collection Types: Table collectiontypes
- All common attributes +
ElementTypePK. Element type PK. Example:8796094496850fromcore-advanced-deployment.xml.typeOfCollection. Type of collection.0= Collection,1= Set,2= List. Example:1fromcore-advanced-deployment.xml.InternalCodeLowerCase. Example:user2owneurope1discountsowneurope1discountscollfromcore-advanced-deployment.xml.
There are about 500 collection types in SAP Hybris Accelerator.
Composed Types: Table composedtypes
- All common attributes +
inheritancePathString. Comma-separated list of PKs that are parents to the item. Example:,8796093055058,8796094431314,8796094464082,fromcore-advanced-deployment.xml.jaloClassName. Example:de.hybris.platform.jalo.Itemfromcore-advanced-deployment.xml.itemJNDIName. Example:de.hybris.platform.persistence.Itemfromcore-advanced-deployment.xml.singleton. Iftrue, the type will be evaluated in a way that allows only one instance per system. Fromcore-advanced-deployment.xml.p_jaloonly. DEPRECATED. Iftrue, the item exists only in the Jalo layer and isn’t backed by an entity bean. Default isfalse.p_dynamic.1for dynamic attributes.SuperTypePK. Super type PK fromcore-advanced-deployment.xml.p_legacypersistence. If true, the system uses the Jalo strategy for managing ACLs. Otherwise, it uses the Service Layer Direct, or SLD, strategy.p_systemtype.1for system types, or null.p_catalogitemtype.1for catalog item types, or null.p_catalogversionattributequali. Name of the attribute that is treated as catalog version, or null. For most items-xml catalog-aware defined types, the value iscatalogVersion.systemVersionis also used for classification catalogs.p_uniquekeyattributequalifier. Comma-separated list of unique attributes of the type.internalCodeLowerCase. Lowercase representation ofinternalCode.removable.1if removable;0if not removable. Fromcore-advanced-deployment.xml.propertyTableStatus. Assumably, it is a leftover from the time when SAP Hybris had one more type-item-related table holding unlocalized properties. This obviously wasn’t really needed, since those properties can live inside the main item table, as they do today. This field was telling which of the two modes was used. In the current versions, it is always1. Fromcore-advanced-deployment.xml.itemTypeCode. A type code, a number associated with the composed type, fromcore-advanced-deployment.xml.p_comparationattribute. Used only for enumeration types;0for sorted.p_localized. Used only for relation types.1for localized relations. See the localized attribute of the relation type declaration. A localized n-m relation can have a link between two items for each language.p_sourceattribute. Used only for relation types. Source attribute for the relations.p_targetattribute. Used only for relation types. Target attribute for the relations.p_sourcetype. Used only for relation types. Source type for the relations.p_targettype. Used only for relation types. Target type for the relations.p_sourcenavigable. Used only for relation types. Indicates whether the relation is navigable from this side. It can only be disabled for one side of a many-to-many relation.p_targetnavigable. The same asp_sourcenavigable, but for the target object.p_orderingattribute. Used only for relation types. Reflects theorderingattribute of the relation tag initems.xml. Contains the PK of the attribute used for ordering,*pos.p_localizationattribute. Unknown to me; it is always null after init for all types.p_previewdisabled. Added bycms2-items.xmlforCMSPageTypethat usescomposedtype.
There are about 1100 composed types in SAP Hybris Accelerator, including:
- ~190 core item types
- About 318 relations
- About 168 enums
Map Types: Table maptypes
- All common attributes +
ArgumentTypePK. PK of the argument type fromcore-advanced-deployment.xml.ReturnTypePK. Return type PK fromcore-advanced-deployment.xml.InternalCodeLowerCase. Internal code lowercased fromcore-advanced-deployment.xml.
Localized Properties: Tables maptypeslp, composedtypeslp, atomictypeslp, collectiontypeslp
These tables contain information about item type properties in different languages.
ITEMPK. PK of the attribute.ITEMTYPEPK. PK of the item type.LANGPK. PK of the language.p_name. Localized name.p_description. Localized description.
Attribute Descriptors: Table attributedescriptors
Attribute descriptors contain information about type attributes.
- All common attributes without Internal Code
qualifierInternal. Name of the attribute from the XML.attributeTypePK. PK of the attribute type. Example:8796095053906forUserDiscountGroup.columnName. Name of the field in the database. Example:p_europe1pricefactory_udgp_defaultvaluedefinitionstring. Examples:Boolean.FALSE,em(). getEnumerationValue( "CmsApprovalStatus", "check")enclosingTypePK. PK of the type this attribute belongs to, such ascustomerList.persistenceQualifierInternal. The CMP, or container-managed persistence, value for persistence type. It was deprecated back in 4.4 and remains only for internal development use.persistenceTypePK. Atomic Type used for storing data. For example:java.util.Datep_attributehandler. Name of the attribute handler, if defined. For example,principalGroupDisplayNameLocalizedAttributeHandler.selectionDescriptorPK. Used mainly for addresses. For example,Address.contactAddresshasselectionDescriptorPK? = AddressCollection.contactAddresses.modifiers. Bitmask: READ(0), WRITE(1), REMOVE(2), OPTIONAL(3), SEARCH(4), PARTOF(5), PRIVATE(7), PROPERTY(8), LOCALIZED(9), INHERITED(10), INITIAL(11), DO NOT OPTIMIZE(13), ENCRYPTED(14), PRIMITIVE(16)p_unique.1if unique.p_hiddenforui.1if the attribute should be hidden from UI. Example:OrgUnit.path Boolean.TRUEp_readOnlyForUI. Example:Product.untypedFeatures Boolean.TRUEp_dontCopy. Example:ProductFeature.stringValue Boolean.TRUEqualifierLowerCaseInternal. Lowercase version of Qualifier.isHidden.1if the attribute is hidden. For example, attributes for storing a relative position in ordered lists are hidden.isProperty.1if the attribute is a property. Attributes withisProperty = 0are not exposed as item type properties; they are considered system properties, such as modified time or saved values.superAttributeDescriptorPK. Example:CustomerList.name -> Principal.name, becauseCustomerListextendsUserGroup,UserGroupextendsPrincipalGroup, andPrincipalGroupextendsPrincipal.inheritancePathString. Comma-separated list of parent types. Example:,8796093841490, 8796094988370, 8796095021138, 8796095479890,p_externalqualifier. External qualifier is used to get or set viade.hybris.platform.util.Config. Used only by the LDAP module and HMC. Used for Config Attribute Descriptors. Example:ldap.jndi.connection.timeoutp_storeindatabase. Used for Config Attribute Descriptors. Used only by the LDAP module and HMC. Example:Boolean.TRUEp_needrestart. Used only by the LDAP module and HMC. Example:Boolean.TRUEp_param. Defines whether the attribute is either a parameter,param=true, or whether it describes a result row attribute,param=false. Example:Boolean.FALSE. Deprecated.p_position. Defines the position of the attribute descriptor. Example:Integer.valueOf(2). Deprecated.p_defaultvalueexpression. Contains the expression for the default value. Example:de.hybris.platform.jalo.JaloSession.getCurrentSession().getUser()p_issource.1if it is a source field in the relation.p_ordered.1for ordered relations.p_relationname. Name of the relation, for relations.p_relationtype. PK of the relation type, for relations.
There is also a table for localized properties:
AttributeDescriptorsLP
Other Tables
Common Attributes
All objects below contain a fixed set of attributes, namely:
PK. A unique key.hjmpTS. Version (bigint). See the section “HJMPTS”. Example:3createdTS. Created time (datetime). Example:2017-07-07 18:22:49.000000modifiedTS. Modified time (datetime). Example:2017-07-07 18:33:26.000000aCLTS.TypePkString. Reference to a type (*types.pk). See the section “PKs”. Example:8796093087826OwnerPkString. PK of the owner.propTS.
Config Items: Table configitems
- All the common attributes above.
Enumeration Values: Table enumerationvalues
- All the common attributes above.
code. An enum value, as a string. Example:CANCELLINGcodeLowerCase. The code in lowercase. Example:cancellingsequenceNumber. A sequence number of the value in the enum. Example:3p_extensionname. Extension name. Example:basecommercep_icon. Media Item PK.editable.1for the editable item.
GenericItems
This table contains the objects of the GenericItem type.
PK. Unique identifier. See the section “PKs”. Example:8796093055075aCLTS.propTS.p_code.
The following attributes are defined by workflow-items.xml, in WorkflowActionTemplateDecisionsTemplateRelation and WorkflowActionDecisionsRelation:
p_actiontemplatep_action.
The following attributes are defined by the AbstractAdvancedSavedQuerySearchParameter and TypedAdvancedSavedQuerySearchParameter definitions in advancedsavedquery-items.xml:
p_comparator.p_emptyhandling.p_valuetype.p_searchparametername.p_joinalias.p_lower.p_wherepart.p_typedsearchparameter.p_enclosingtype
There is also a table for localized properties:
GenericItemLP
gentestitems
This table contains the instances of GenericTestItem used in the test classes.
hjmpTS. Version (bigint). See the section “HJMPTS”. Example:3createdTS. Created time (datetime). Example:2017-07-07 18:22:49.000000modifiedTS. Modified time (datetime). Example:2017-07-07 18:33:26.000000TypePkString. Reference to a type (*types.pk). See the section “PKs”. Example:8796093087826OwnerPkString.PK. Unique identifier. See the section “PKs”. Example:8796093055075aCLTS.propTS.
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.
hjmpTS.createdTS.modifiedTS.TypePkString.OwnerPkString.PK.languagepk.Qualifier.SourcePK.TargetPK.SequenceNumber.RSequenceNumber.aCLTS.propTS.
mediaprops
See the information about props tables above.
hjmpTS.ITEMPK.ITEMTYPEPK.NAME.LANGPK.REALNAME.TYPE1.VALUESTRING1.VALUE1.
metainformations
Hybris saves tenant information here.
hjmpTS.PK.createdTS.modifiedTS.aCLTS.TypePkString.OwnerPkString.propTS.SystemPK.SystemName.isInitialized. This field says whether the system is initialized or not.LicenceID.LicenceName.LicenceEdition.AdminFactor.LicenceExpiration.LicenceSignature.
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.
hjmpTSserieskey— the key.pk_is used for generating PKs of the objects.seriestype— there are two types: alphanumeric (0) and numeric (1).currentValue— current value. The unique IDs are generated in blocks of the specified size.currentvaluecontains the last ID of the generated sequence.template— template defines the key format.@is used to inject PK, and$is used to inject a numeric value of the key.
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:
hjmpTScreatedTSmodifiedTSTypePkStringOwnerPkStringPKLanguagePkQualifierSourcePKTargetPKSequenceNumberRSequenceNumberaCLTSpropTS
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.
hjmpTScreatedTSmodifiedTSTypePkStringOwnerPkStringPKp_extensionnamep_autocreatep_generatep_codep_activeprincipalqueryRestrictedTypeaCLTSpropTS
There is also a table for localized properties:
SearchRestrictionLP
testitem
TestItem is used in unit tests. There are fields of different types.
hjmpTScreatedTSmodifiedTSTypePkStringOwnerPkStringPKfieldAfieldBfieldBooleanfieldBytefieldCharacterfieldDatefieldDoublefieldFloatfieldIntegerfieldLongfieldPrimitiveBooleanfieldPrimitiveBytefieldPrimitiveCharfieldPrimitiveDoublefieldPrimitiveFloatfieldPrimitiveIntegerfieldPrimitiveLongfieldPrimitiveShortfieldSerializablefieldStringfieldLongStringp_testproperty0aCLTSpropTSfieldBigDecimalp_testproperty1p_foop_barp_xxxp_itemtypetwop_itemstypetwo
ydeployments
This table contains information about type deployments: what table corresponds to what type, and what configuration options should be taken into account.
hjmpTSTypecodeTableNamePropsTableNameNamePackageNameSuperNameExtensionNameModifiersTypeSystemName
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
@Versionannotation.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
WHEREclause 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(defaultfalse) 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.exceptionsparameter totruein properties activates optimistic locking and, of course, increases the risk of seeing optimistic concurrency exceptions, such asHJMPException(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)