2 August 2019

Liferay: From 6.2 to 7.1 the Model is the key to Services, Security and Search.

I have been struggling with bringing legacy Liferay 6.x code into Liferay 7.1. The biggest reason is the legacy models/entities have not matched the expectations of the 7.1 framework. If your model meets these expectations,they have a path for you that is smooth and will take you where you need to go. You can still get there if your model is missing the expected, eventually. It isn’t currently a documented path. For me it has been a rough trip. This and other articles to follow will hopefully ease your journey.

Liferay does document what should be in your model. The legacy code didn’t have all that was needed and the Liferay code examples require it. Services, Security and Search code examples will not compile or not work as expected. These requirements did exist in Liferay 6.x, but were loosely enforced. Let’s start with a list of what Liferay expects to be in your model. Below I have an example service.xml file.


<?xml version="1.0"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 7.1.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_7_1_0.dtd">

<service-builder package-path="com.example">
	<entity local-service="true" name="Foo" remote-service="true"

		<!-- PK fields -->

		<column name="fooId" primary="true" type="long" />

		<!-- Group instance -->

		<column name="groupId" type="long" />

		<!-- Audit fields -->

		<column name="companyId" type="long" />
		<column name="userId" type="long" />
		<column name="userName" type="String" />
		<column name="createDate" type="Date" />
		<column name="modifiedDate" type="Date" />


The name of your primary key will vary but should of type long. Its possible to have a primary key that is a different data type. I strongly recommend that you have a long primary key. Some Liferay security interfaces require it. Dates are not supported as primary keys. Not even if they are part of a composite primary key. The rest of the columns need to the be in the entity as shown and they need to be properly populated. This will ensure that the code examples will work for you.

Lets talk about groupId. GroupIds represent Sites in Liferay. As you might expect Sites are a “group” of pages (layouts). Users are members of Sites. From the Liferay perspective it makes sense. Many applications (portlets) are designed for a broad audience. You probably want to secure the data from the user, site and company levels. Many users can belong to a site. Many sites can belong to a company. In my situation there is only one company configured. Much of the data is shared across organizational lines. It didn’t make sense to secure it at the site level when the data was going to be shared among multiple sites. The best way to handle such a situation would be to leave groupId in the entity and populate with a zero. The Liferay API checks for a groupId of zero in search and security. It then handles it in an alternative fashion.

Now that we have stressed the importance of the model I see two paths. One is the path of Liferay 7.1 New Code and Liferay 7.1 Legacy Upgrade.

tags: java - liferay - search - service builder - security

Less Is More