Custom Attributes / Custom Fields in Liferay

If you are working with Liferay and you need to store some data, say about a User, you will not always create a new service. Sometimes it´s just a property that needs to be stored and a new Service would be overweight for this requirement. This is the time to create Custom Attributes or Custom Fields as they are called in Liferay 6.

List of Custom Fields in the Liferay Control Panel (Liferay 6)
But no matter how they are called on the GUI - they are Expando values on the inside. This post will show you how to set and retrieve expando values programmatically.

ExpandoValues can be added to a lot of liferay objects: Users, Organizations, Pages, Images, Calendar Events etc. If you store a value, either by using the Control Panel or programmatically they will be stored using the following structure. Note that you have to know this structure for storing and retrieval. The examples on how to actually retrieve or store something will follow later down.


This table stores the information which tableId matches which classname (= entity). To find out the className that matches your entity, simply query the ClassNameLocalServiceUtil:

long userClassNameId = ClassNameLocalServiceUtil.getClassNameId(User.class.getName());

Now, get the tableId you need for the User table:
ExpandoTable table = ExpandoTableLocalServiceUtil.getDefaultTable(companyId, userClassNameId );
The information about the default table for your entity is something you need to get the data out of the database.


ExpandoColumns holds the information, which columnId matches the type of expando value you want to retrieve or store. Use it, to get the last information to retrieve or store your data:
ExpandoColumn column = ExpandoColumnLocalServiceUtil.getColumn(tableId, name);
You can retrieve the column with the tableId and its name.


The ExpandoValue table holds all values that are stored in the liferay portal. And this is one of the main reasons why you should never ever store too much data in custom fields: they all land in ONE table !!!!! Never use custom attributes to store something, a service is made for !!!

To retrieve a value use the following line of code:
ExpandoValueLocalServiceUtil.getValue(tableId, columnId, classPK);
tableId is the id of your default  table, columnId the id of the retrieved column and classPK the primary Key of the entity you want to retrieve. In our example it would be the userId.

To store an expando value, it´s just the other way around:
ExpandoValueLocalServiceUtil.addValue(classNameId, tableId, columnId, classPK, data);
Should be pretty straight forward.

If you like this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.