Defining Relation in items.xml in Hybris
Relation types help us to maintain the m:n relation between 2 tables.
Let’s consider 2 possible cases in relation
Case 1:
One to Many/Many to One
One user can have any number of contacts
- <relation code="User2ContactInfos" generate="true" localized="false" autocreate="true">
- <sourceElement type="User" cardinality="one" qualifier="user">
- <modifiers read="true" write="true" search="true" optional="false"/>
- </sourceElement>
- <targetElement type="AbstractContactInfo" cardinality="many" qualifier="contactInfos" ordered="true">
- <modifiers read="true" write="true" search="true" optional="true" partof="true"/>
- </targetElement>
- </relation>
<relation code="User2ContactInfos" generate="true" localized="false" autocreate="true"> <sourceElement type="User" cardinality="one" qualifier="user"> <modifiers read="true" write="true" search="true" optional="false"/> </sourceElement> <targetElement type="AbstractContactInfo" cardinality="many" qualifier="contactInfos" ordered="true"> <modifiers read="true" write="true" search="true" optional="true" partof="true"/> </targetElement> </relation>
We can see below entries in model class after build
UserModel.java
- private Collection<AbstractContactInfoModel> _contactInfos;
private Collection<AbstractContactInfoModel> _contactInfos;
AbstractContactInfoModel.java
- private UserModel _user;
private UserModel _user;
Since its a One To Many relation, we can observe that Collection is generated in UserModel class and just single User entity is generated in AbstractContactInfoModel class
Case 2:
Many to many
Consider the relation between Product and categories
One product can belong to many categories
And one category can contain many products.
It is m:n relation.
We can define the relation for such case as below
- <relation code="CategoryProductRelation" autocreate="true" generate="true" localized="false">
- <deployment table="Cat2ProdRel" typecode="143"/>
- <sourceElement qualifier="supercategories" type="Category" cardinality="many" ordered="false">
- <description>Super Categories</description>
- <modifiers read="true" write="true" search="true" optional="true"/>
- </sourceElement>
- <targetElement qualifier="products" type="Product" cardinality="many" collectiontype="list" ordered="true">
- <description>Products</description>
- <modifiers read="true" write="true" search="true" optional="true"/>
- </targetElement>
- </relation>
<relation code="CategoryProductRelation" autocreate="true" generate="true" localized="false"> <deployment table="Cat2ProdRel" typecode="143"/> <sourceElement qualifier="supercategories" type="Category" cardinality="many" ordered="false"> <description>Super Categories</description> <modifiers read="true" write="true" search="true" optional="true"/> </sourceElement> <targetElement qualifier="products" type="Product" cardinality="many" collectiontype="list" ordered="true"> <description>Products</description> <modifiers read="true" write="true" search="true" optional="true"/> </targetElement> </relation>
We have defined the relation with code “CategoryProductRelation”
Speicifed the deployment table called “Cat2ProdRel”
We have 2 important things here,sourceElement and targetElement.
We can see that cardinality is mentioned as many in source and many in target, so it’s a many to many relation.
We can see qualifier as superCategories in the source which is of type Category.
We can see qualifier as products in the target which is of type Product.
It means Inside a Category it creates a variable called products and inside a Product it creates a variable called superCategories
Generate will have no effect for relation.
Autocreate true makes the relation type to be created.
We have specified collection type as List for target.
After the build, we can see below entries in java class
CategoryModel.java
- private List<ProductModel> _products;
private List<ProductModel> _products;
ProductModel.java
- private Collection<CategoryModel> _supercategories;
private Collection<CategoryModel> _supercategories;
How Relation works in backend?
One table will be created for Products
One table will be created for Categories
One extra table will be created for LinkItem(elements on both sides of the relation are linked together via instances of a LinkItem table)
Each LinkItem instance stores the PKs of the related items for each row.
So every row of product with associated category will have one row in the LinkItem table with PK of Catrgory and associated PK of Product.
LinkItem instances are used internally by hybris.
We just need to call getters and setters at the API level to set and get the values.
Note:
Extra table will be created only for many to many relations
Hi KB,
can you explain what is the use of Partof and ordered attribute?
Here value of Partof is true that means ‘user’ and ‘contactInfos’ are linked in such a way that if user is deleted, ‘contactInfos’ will be deleted automatically.
Hi,
Could please explain how to implement Many-to-Many Association with additional Attributes Relation in Hybris !?
Thank You !
Hi
Can we define 1:1 relationship in hybris?
Please explain
WIthout deployment table, we can create many to many relation or not?
Hi, is there possible to override an existing relation or redefine it? if yes, how can i achieve that? regards
After we successfully create a m:n relationship between two itemtypes and run the application and do all stuff,now can we change the relation type to 1:n.If yes then how and what impact will it make.
Hi Karibasappa,
Thanks for all the information provided, it’s very helpful.
Let me understand something, why do we need the relations? It is not posible to link tables with SQL en our code? Is it necesary to use relation types or it just improves performance?
Another thing that confuses me is that you explain that it helps for M:N relations but then you share a 1:N example.
Thanks!!
Hi,
I am assuming , you are asking about linking tables through SQL script using foreign key reference and answering it accordingly,
If you do so, then How flexible search query will understand your changes in the back-end when you are trying to retrieve data.
Secondly , it is easy to define relations in XML rather writing all those scripts.
I explained both one to many and many to many relations in this article, Please read it again to understand both.
Hope it clarifies you !!
Hi KB,
Can you please explain the meaning of localized=”false”
A localized =”true” means it will have a link between two items for each language and in “false” case there will not be such relation for each language.
Hi when i am using localized=”true” my code is working fine in HMC but when i am using backoffice it is giving me error
use of partof=”true ??
and
ordered=”false”
ordered=”true in above One to Many/Many to One
How to make one to many relation unidirectional ? By default in relation its bi-directional .
And how to make any attribute mandatory @ initialization ?
Hi KB, why we defined deployment tag in m:m relation and why not for 1:m and m:m.
Hi Rani,
M:N relation requires another table to store the PKs of both source and target table.
Please read below article for more information on Many to Many relation
http://javainsimpleway.com/many-to-many-xml-mapping-in-hibernate/
Thq kb.. And whether it will create temporary table or permanent table in db.
It will be permanent one !!
Hi
When we define a target element in the relation type so it try to find out this target element in the same extension item.xml file or extension in which it’s defined. e.g cuppyTrail is dependent on cuppy and target element item type in cuppytrail extension is defined in cuppy extension.
Its fine if its defined in dependent extension
Hi Karibasappa
Can you please explain what you mean by extra table is only created for m:n relation?
relation table is not made for m:1 or 1:m relations?
Please check below article
http://javainsimpleway.com/many-to-many-xml-mapping-in-hibernate/