What is Service Builder?
Service Builder is a model-driven code generation tool built by Liferay that allows developers to define custom object models called entities. Service Builder generates a service layer through object-relational mapping (ORM) technology that provides a clean separation between your object model and code for the underlying database. This frees you to add the necessary business logic for your application. Service Builder takes an XML file as input and generates the necessary model, persistence, and service layers for your application. These layers provide a clean separation of concerns. Service Builder generates most of the common code needed to implement create, read, update, delete, and find operations on the database, allowing you to focus on the higher level aspects of service design. In this section, we’ll discuss some of the main benefits of using Service Builder:
- Integration with Liferay
- Automatically generated model, persistence, and service layers
- Automatically generated local and remote services
- Automatically generated Hibernate and Spring configurations
- Support for generating finder methods for entities and finder methods that account for permissions
- Built-in entity caching support
- Support for custom SQL queries and dynamic queries
- Saved development time
Liferay uses Service Builder to generate all of its internal database persistence code. In fact, all of Liferay’s services, both local and remote, are generated by Service Builder. Additionally, the plugins’ services in Liferay’s Plugins SDK are generated by Service Builder. Service Builder’s use in Liferay Portal and Liferay plugins demonstrates it to be a robust and reliable tool. As we’ll see throughout this chapter, Service Builder is easy to use and can save developers lots of development time. Although the number of files Service Builder generates can seem intimidating at first, developers only need to work with a few files in order to make customizations to their applications and add business logic.
Note: You don’t have to use Service Builder for plugin or portlet development. It’s entirely possible to develop Liferay plugins by writing custom code for database persistence using your persistence framework of choice, such as JPA or Hibernate.
One of the main ways Service Builder saves development time is by completely eliminating the need to write and maintain database access code. To generate a basic service layer, you only need to create a
service.xml file and run Service Builder. This generates a new service
.jar file for your project. The generated service
.jar file includes a model layer, a persistence layer, a service layer, and related infrastructure. These distinct layers represent a healthy separation of concerns. The model layer is responsible for defining objects to represent your project’s entities, the persistence layer is responsible for saving entities to and retrieving entities from the database, and the service layer is responsible for exposing CRUD and related methods for your entities as an API. The code Service Builder generates is database-agnostic, as is Liferay itself.
Each entity generated by Service Builder contains a model implementation class, a local service implementation class, and optionally a remote service implementation class. Customizations and business logic can be implemented in these classes; in fact, these are the only classes generated by Service Builder that are intended to be customized. Ensuring that all customizations take place in only a few classes makes Service Builder projects easy to maintain. The local service implementation class is responsible for calling the persistence layer to retrieve and store data entities. Local services contain the business logic and access the persistence layer. They can be invoked by client code running in the same Java Virtual Machine. Remote services usually have additional code for permission checking and are meant to be accessible from anywhere over the Internet or your local network. Service Builder automatically generates the code necessary to allow access to the remote services. The remote services generated by Service Builder include SOAP utilities and can be accessed via SOAP or JSON.
Another way Service Builder saves development time is by providing Spring and Hibernate configurations for your project. Service Builder uses Spring dependency injection for making service implementation classes available at runtime and uses Spring AOP for database transaction management. Service Builder also uses the Hibernate persistence framework for object-relational mapping. As a convenience to developers, Service Builder hides the complexities of using these technologies. Developers can take advantage of Dependency Injection (DI), Aspect Oriented Programming (AOP), and Object-Relational Mapping (ORM) in their projects without having to manually set up a Spring or Hibernate environment or make any configurations.
Another benefit of using Service Builder is that it provides support for generating finder methods. Finder methods retrieve entity objects from the database based on specified parameters. You just need to specify the kinds of finder methods to be generated in the
service.xml configuration file and Service Builder does the rest. The generated finder methods allow you, for example, to retrieve a list of all entities associated with a certain site or a list of all entities associated with a certain site and a certain user. Service Builder not only provides support for generating this kind of simple finder method but also for finder methods that take Liferay’s permissions into account. For example, if you are using Liferay’s permissions system to protect access to your entities, Service Builder can generate a different kind of finder method that returns a list of entities that the logged-in user has permission to view.
Service Builder also provides built-in caching support. Liferay caches objects at three levels: entity, finder, and Hibernate. By default, Liferay uses Ehcache as an underlying cache provider for each of these cache levels but this is configurable via portal properties. All you have to do to enable entity and finder caching for an entity in your project is to set the
cache-enabled=true attribute of your entity’s
<entity> element in your
service.xml configuration file. Please refer to the Liferay Clustering section of Using Liferay Portal 6.2 for more details about Liferay caching.
Service Builder is a flexible tool. It automates many of the common tasks associated with creating database persistence code but it doesn’t prevent you from creating custom SQL queries or custom finder methods. Service Builder allows developers to define custom SQL queries in an XML file and to implement custom finder methods to run the queries. This could be useful, for example, for retrieving specific pieces of information from multiple tables via an SQL join. Service Builder also supports retrieving database information via dynamic query.
In summary, we encourage developers to use Service Builder for portlet and plugin development because it’s a proven solution used by many Liferay plugins and by Liferay Portal itself. It generates distinct model, persistence, and service layers, local and remote services, Spring and Hibernate configurations, and related infrastructure without requiring any manual intervention by developers. It also allows basic SQL queries and finder methods to be generated and ones that filter results, taking Liferay’s permissions into account. Service Builder also provides support for entity and query caching. Each of these features can save lots of development time, both initial development time and time that would have to be spent maintaining, extending, or customizing a project. Finally, Service Builder is not a restrictive tool: it allows custom SQL queries and finder methods to be added and it also supports dynamic query. Next, let’s roll up our sleeves and learn how to use Service Builder.