Liferay Design Patterns - Multi-Scoped Data/Logic

Pattern: Multi-Scoped Data/Logic

Intent

The intent for this pattern is to support data/logic usage in multiple scopes. Liferay defines the scopes Global, Site and Page, but from a development perspective scope refers to Portal and individual OSGi Modules. Classic data access implementations do not support multi-scope access because of boundaries between the scopes.

The Multi-Scoped Data/Logic Liferay Design Pattern's intent is to define how data and logic can be designed to be accessable from all scopes in Liferay, either in the Portal layer or any other deployed OSGi Modules.

Also Known As

This pattern is implemented using the Liferay Service Builder tool.

Motivation

Standard ORM tools provide access to data for servlet-based web applications, but they are not a good fit in the portal because of the barriers between modules in the form of class loader and other kinds of boundaries. If a design starts from a standard ORM solution, it will be restricted to a single development scope. Often this may seem acceptable for an initial design, but in the portal world most single-scoped solutions often need to be changed to support multiple scopes. As the standard tools have no support for multiple scopes, developers will need to hand code bridge logic to add multi-scope support, and any hand coding increases development time, bug potential, and time to market.

The motivation for Liferay's Service Builder tool is to provide an ORM-like tool with built-in support for multi-scoped data access and business logic sharing. The tool transforms an XML-based entity definition file into layered code to support multiple scopes and is used throughout business logic creation to add multi-scope exposure for the business logic methods.

Additionally the tool is the foundation for adding portal feature support to custom entities, including:

  • Auto-populated entity audit columns.
  • Asset framework support (comments, rankings, Asset Publisher support, etc).
  • Indexing and Search support.
  • Model listeners.
  • Workflow support.
  • Expando support.
  • Dynamic Query support.
  • Automagic JSON web service support.
  • Automagic SOAP web service support.

You're not going to get this kind of integration from your classic ORM tool...

And with Liferay 7 CE / Liferay DXP, additionally you also get an OSGi-compatible API and service bundle implementation ready for deployment.

Applicability

IMHO Service Builder applies when you are dealing with any kind of multi-scoped data entities and/or business logic; it also applies if you need to add any of the indicated portal features to your implementation.

Participants

The participants in this pattern are:

  • An XML file defining the entities.
  • Spring configuration files.
  • Implementation class methods to add business logic.
  • Service consumers.

The participants are used by the Service Builder tool to generate code for the service implementation details.

Details for working with Service Builder are covered in the following sections:

Collaboration

ServiceBuilder uses the entity definition XML file to generate the bulk of the code. Custom business methods are added to the ServiceImpl and LocalServiceImpl classes for the custom entities and ServiceBuilder will include them in the service API.

Consequences

By using Service Builder and generating entities, there is no real downside in the portal environment. Service Builder will generate an ORM layer and provide integration points for all of the core Liferay features.

There are three typical arguments used by architects and developers for not using Service Builder:

  • It is not a complete ORM. This is true, it does not support everything a full ORM does. It doesn't support Many To Many relationships and it also doesn't handle automatic parent-children relationships in One To Many. All that means is the code to handle many to many and even some one to many relationship handling will need to be hand-coded.
  • It still uses old XML files instead of newer Annotations. This is also true, but this is more a reflection of Liferay generating all of the code including the interfaces. With Liferay adding portal features based upon the XML definitions, using annotations would require Liferay to modify the annotated interface and cause circular change effects.
  • I already know how to develop using X, my project deadlines are too short to learn a new tool like Service Builder. Yes there is a learning curve with Service Builder, but this is nothing compared to the mountains of work it will take getting X working correctly in the portal and some Liferay features will just not be options for you without Service Builder's generated code.

All of these arguments are weak in light of what you get by using Service Builder.

Sample Usage

Service Builder is another case of Liferay eating it's own dogfood. The entire portal is based on Service Builder for all of the entities in all of the portlets, the Liferay entities, etc.

Check out any of the Liferay modules from simple cases like Bookmarks through more complicated cases such as Workflow or the Asset Publisher.

Conclusion

Service Builder is a must-use if you are going to do any integrated portal development. You can't build the portal features into your portlets without Service Builder usage.

Seriously. You have no other choice. And I'm not saying this because I'm a fanboy or anything, I'm coming from a place of experience. My first project on Liferay dealt with a number of portlets using a service layer; I knew Hibernate but didn't want to take time out to learn Service Builder. That was a terrible mistake on my part. I never did deal with the multi-scoping well at all, never got the kind of Liferay integration that would have been great to have. Fortunately it was not a big problem to have made such a mistake, but I learned from it and use Service Builder all the time now in the portal.

So I share this experience with you in hopes that you too can avoid the mistakes I made. Use Service Builder for your own good!

Blogs
Hello David,

Thanks for sharing your experiences with what looks like a very good framework that's well integrated with Liferay portal.

Although there are concerns that you and other people have raised such as the need for additional logic to handle foreign keys and may-to-many relationships, I am wondering how well does the Service Builder framework scale? In other words is it, in your opinion, suitable for medium to large scale projects?

The other concern is whether the framework is suitable for existing applications with existing databases or is it only suitable for greenfield projects?

Many thanks
Yaseen
Service Builder code leverages Liferay caching based on ehcache and also works well dealing with cluster changes. SB adds layers on top of Hibernate so the performance characteristics at that level are on par with pure Hibernate, so scaling is not an issue. Liferay itself uses SB for every aspect of the portal data access, so they are very concerned about SB performance in general and have tuned it appropriately.

SB works with both new and existing tables. In the <entity /> tags you can add attributes for existing tables and the <column /> tags also have a db-name attribute to map to an existing column name. Plus you can connect to any external database so you are not limited to the Liferay database.

Many, many large scale Liferay projects have successfully leveraged Service Builder for their data access needs.
Service Builder indeed handles the weird runtime class loading issues that you have to deal with a portal environment. However all of the features pale in comparison with the fact that you become dependent on a proprietary piece of tech that has dozens of painful little peculiarities. Of course as you become more familiar with each one of them, the hard way, you gain experience with the tool and the Liferay platform. However, and this is my main gripe, in the end your project will have become tightly coupled to a non standard tech, with its own APIs and schemas and behaviors and everything.

We just finished a migration of a medium to big project from Liferay 6.1 to 6.2. Service builder was one of the major headaches we had to deal with - the other was alloy ui. Here is another drawback of SB. Code built for Liferay version X works only with that exact version. Even a minor .1 Liferay upgrade will require a migration of the whole service codebase - which is absurd if you think about it.
Yes you are tethered to Liferay. But honestly if you believe you could pick up your non-SB code and move it to some other platform and get it to work, well then you're fooling yourself. You are developing for Liferay. It's only going to run on Liferay and, regardless how closely you code to the portlet specs, you're never going to run your portlets on some other platform.

Once you can accept that, you can embrace all that Liferay has to offer and build cohesive and integrated solutions. That's the key part. Your site visitors don't care about what technologies you used, how hard your upgrade was, etc - they just care about site usability and cohesion. When you don't have these things, that's when you get complaints about the site.

All of that aside, I feel your upgrade pain. I too have hit that, and I've been doing upgrades since Liferay 4. That was much harder, 4->5 was Prototype -> jQuery, 5->6 was jQuery to AUI, ...

Each upgrade is a pain. If you think about it, it's hard to integrate the latest web trends and maintain backwards compatibility to an old JS framework that has not been updated.

I'm sorry you found the 6.1 to 6.2 migration so hard; outside of the AUI changes, that has been one of the easier upgrades I've gone through. The SB part of the migration should not have been as difficult though, especially since there weren't many changes there as I recall...