Creating Service layer in Service Builder in Liferay

Service builder is an automated tool to construct service and persistence layer in Liferay. We need to define business models (entities) and rest is taken care by service builder.

Service Builder is one of the most powerful, time saver, proven and peace of mind feature of Liferay.

what is Liferay Service Builder ?

Liferay provide nice way of creating service and persistence layer. Liferay Service Builder is a tool to create service-persistence layer in Liferay. It generates set of classes and interfaces which is used to interact with Database (CRUD operation). This way it saves development time of building service-persistence layer manually. You can refer my previous blog on Liferay Service Builder concept to get little more background bout it.

Liferay Service Builder uses Spring for providing Service layer implementation and Hibernate for persistence layer implementation. Both of these frameworks (Spring & Hibernate) are industry standard and proven to construct scale-able web applications.

Let us see how to develop service-persistence layer in liferay by simple example. First we need to create custom Liferay MVC Portlet.

Give project name as service-builder-test and eclipse will append -portlet at the end so that final project name will become service-builder-test-portlet.Create portlet class call called  TestServiceBuilderPortlet under package com.opensource.techblog.portlet. Also update portlet class entry in portlet.xml file. After this the project structure will look like below screenshot.

Creating Service layer by Service Builder in Liferay - Service Builder

We want to create  service and persistence layer that will actually provide CRUD operations.

In Real life, the business objects are encapsulated by Entity classes. From an object-oriented perspective, an entity object represents an object in the real-world problem domain (Business Object). Each Business object will have attributes and behaviour (instance variable and methods in Object Oriented perspective).

In our case we will take Student as business object. In real world Student will have following attributes

  • Name
  • Age
  • Father Name
  • Mother Name
  • Standard
The goal of this article is to create CRUD methods to save / update /add /remove Students details into database.

Service layer by Service Builder

Please following below steps to create service for Student entity.
Right click on Project in Eclipse, choose New –>Liferay Service. It will show following window asking to enter Package Path, Name space, and Author name
Creating Service layer by Service Builder in Liferay - Creating Service.xml from Eclipse

Creating Service layer by Service Builder in Liferay - Add-Service-builder-detail
Explanation:-

Package Path :- the location where the generated service-persistence classes will resides.
Namespace :- Back end side, liferay will create SQL script for each entity. We can group the tables generated for entities by giving Name Space value.

For Example, 

  • If we give Name space as education and if we defined 3 entities (soon we see how to define the entities) then there will be 3 tables created (each for individual entity).
  • Name of these (3) tables will start with education_. 
  • Suppose the entities are Student, Marks and Leave then the corresponding table name would be education_student, education_marks and education_leave.

The generated Tables for each entities defined in service.xml file will have common namespace defined in that service.xml file
Author :- Name of the author who is going to create the services.

We can define multiple entity in service.xml. For simplicity, we took just one entity. Give the value for Package Name, Namespace and Author name as below.

Package path:- com.opensource.techblog.myservice
Namespace:- education
Author:- <<Your Name>> (I gave mine)

Click on Finish button. You will observe that a new file called service.xml will be created under WEB-INF folder as shown in below screenshot.

Creating Service layer by Service Builder in Liferay - service.xml-file-created

You can observe that the package-path, author and namespace will be defined as elements in service.xml. Now we will start defining our entity – Student. Add the following snippet (for Student entity) in service.xml file.


Explanation:-

  • Liferay service builder can generate local or remote or both type of services. Local service can be used by client code running in same VM(Virtual Machine) where liferay instance is running. Liferay also supports remote service which can be accessed as a web-service (SOAP or JSON) over internet / intranet. In our case we have created Student entity by defining local-service as true and remote-service as false so it will generate only local service.
  • Child elements of Student element’s are columns which exactly reflect the column in the DB table.
  • Each column will have name and type. We can declare the primary key by giving primary=”true”. If more than one column defined as primary=”true” then compound key will be generated.
  • The available column types are
  • long
  • int
  • String
  • boolean
  • Date
  • Blob etc.
We have done our homework. it’s lifera’y turn now. We only have to declare the entities in service.xml file and rest all will be taken care by liferay. Let’s see how the magic is happening behind the scene.

go to command prompt up to service-builder-test-portlet and give command ant build-service. It should show the below text in console and at the end it will show the message “Build Successful”.

Creating Service layer by Service Builder in Liferay - Sucessful-Build

Now come back to portlet in eclipse and right click on project service-builder-test-portlet and click on Refresh. At this stage, the project structure looks like below screenshot.

Creating Service layer by Service Builder in Liferay - service-class-generated

You will observe that few classes / files are added in project as shown in below screenshot. They all are related to service-persistence layer. Let’s see all them in details. 

As shown in the screenshot, the generated service classes are located at following two places

  • /WEB/INF/service/com/opensource/techblog/myservice
    • Which contains util classes and interface.
    • All the interface / classes resides under this location will be packed in JAR file. This jar file will be generated after each service build (through ant build-service command).
    • So the interfaces and util classes can be available directly to outer world.
  • /WEB-INF/src/com/opensource/techblog/myservice
    • which contains the implementation of interfaces defined under folder /WEB-INF/service/com/opensource/techblog/myservice.
    • It will be part of class path (under src folder) and will not be directly available to outer word.
Classes and interfaces which are generated at service , persistence and model layer.


Persistence Layer:-

  • StudentPersistence.java (under /WEB/INF/service/com/opensource/techblog/myservice)
    • Student persistence interface which defines CRUD methods related to Student entity like create, remove, countAll, find, findAll etc
  • StudentPersistenceImpl.java (under /WEB-INF/src/com/opensource/techblog/myservice)
    • This is the implementation class, which implements StudentPersistence.
  • StudentUtil.java (under /WEB/INF/service/com/opensource/techblog/myservice)
    • This util class, which having the instance of StudentPersistenceImpl class


Service Classes:-

  • StudentLocalService.java
    • local service interface for Student entity.
  • StudentLocalServiceImpl.java
    • local service implementation which implements StudentLocalService interface. Basic CRUD methods will be added by liferay service builder. If you want to add any additional service methods then must be added in this class.
    • However you can’t directly access them from this class. You have to re-run the service builder (through ant build-service command) and service builder will create corresponding (same method signature) static method in StudentLocalSerivceUtil class. You can then access StudentLocalSeriviceUtil class which internally make call to corresponding (same signature) method of StudentLocalServiceImpl.
  • StudentLocalServiceBaseImpl.java
    • This class implements StudentLocalSerivce interface and provides all basic CRUD methods. StudentLocalServiceImpl where we can define additional service methods extends this class.
    • All service Impls and persistence Impls classes related to Student entity are injected into this class. Additionally if you give reference of any other entity, it’s service impls and persistence impls classes are also injected in this class.
  • StudentLocalServiceUtil.java
    • Object of type StudentLocalServiceImpl is injected in StudentLocalServiceUtil class by Liferay service builder through spring injection. Out of all above service classes, only this class is accessible to other API (outside of service layer) for CRUD operation.
    • StuddentLocalServiceUtil has all static method. Each method of StudentLocalServiceUtil will make call to corresponding (same signature) method in StudentLocalSerivceImpl class.

Model classes:-

Model class Represent a row in education_student table.

  • StudentModel.java
    • Base model (interface) for Student.
    • This interface and its corresponding implementation (StudentModelImpl) exist only as a container for the default property accessors generated by ServiceBuilder. Helper methods and all application logic should be put in (StudentImpl)
  • StudentModelImpl.java
    • Base model impl which implements StudentModel interface
    • This implementation and its corresponding interface (StudentModel) exist only as a container for the default property accessors generated by ServiceBuilder. Helper methods and all application logic should be put in (StudentImpl).
  • Student.java
    • extends studentModel.java
    • By defaul there is not method defined.
    • Whenever any new (custom) method added to StudentImpl, they will be added to this interface on next service build.
  • StudentImpl.java
    • extends StudentBaseImpl.java.
    • implements Student.java interface.
    • Helper methods and all application logic should be put in this class.
    • Whenever custom methods are added in this class, the corresponding methods will be added to Student interface on next service build.

Relations among Model interfaces / classes :-

Following diagram shows the relation between  model interface and classes 

Out of these model classes / interfaces, only StudentImpl.java is allowed to add additional (custom) methods at model level to developer. Creating Service layer by Service Builder in Liferay - Service_Builder_ModelpngRelations among Service interfaces / classes :-

Following diagram shows the relation between  service interface and classes 

Creating Service layer by Service Builder in Liferay - Service_Builder_Service

Out of these service classes / interfaces, only StudentLocalServiceImpl is allowed to add additional (custom) methods at service level to developer.


Relations among  Persistence interfaces / classes :-

Following diagram shows the relation between  persistence interface and classes
Creating Service layer by Service Builder in Liferay - Service_Builder_Persistence
None of the class is allowed to add customized methods to developer. 
So this is all about service layer generated by liferay for each entity.StudentLocalServiceUtil class is available to outer world (Portlet and other plugins) to perform CRUD operation. It contains following methods. We can call them in our portlet to Add / update / delete Students.
Creating Service layer by Service Builder in Liferay - StudentLocalServiceUtil

You will observe that this class have various CRUD methods like

  • createStudent
  • addStudent
  • deleteStudent
  • updateStudent
  • fetchStudent
  • getStudent.
Note that, this class have instance variable of type StudentLocalService, which will get the instance of StudentLocalServiceImpl at run time (by spring injection). We can’t call methods of StudentLocalServiceImpl class directly. Liferay service builder will create corresponding methods of StudentLocalServiceImpl class with same method signature in StudentLocalServiceUtil class.’
All methods of this (StudentLocalServiceUtil) class will internally call corresponding method of StudentLocalServiceImpl to perform CRUD operation. In general, you have access to XXXLocalServiceUtil class (Where XXX represents entity name). All methods of XXXLocalServiceUtil class will internally call method of XXXLocalServiceImpl class.
And that’s all. You can create more than one entity to understand the underlying class structure generated by liferay.
Please read following blogs to get idea of more feature of Service builder in Liferay

Summing Up

  • Service builder is used to create service and persistence layer in Liferay
  • We need to define business model and service builder will take care for rest.
  • Service builder creates set of service and persistence classes and interface.
  • Go to Liferay documentation and search for Service Builder to get more idea.

Share This Post

50 Comments - Write a Comment

  1. at service layer I build two entities successfully and related table also created in Database but at third entity service builder run successfully but related entity table not created in Database. I am create table as manually in Database.Please help me.

    Reply
    1. Hello Prasanna,

      Welcome to Techblog. Follow below steps

      1) You need to build the service first and then have to deploy. Until you deploy, there won’t be any changes done on database side.
      2) Are you using service-ext.properties file ? If yes, then you have to manually increase the build numbers, build the service and have to deploy it again to reflect your changes in DB.

      By the way which Liferay version you are using ?

      Regards
      Nilang

      Reply
  2. Hi Nilang,

    I tried and still things are not working 🙁 Do you have the complete war or rar file, which does the image upload to cusotm table in DB? I meant any working custom portlet. I am using Liferay 6.1.1 GA3 version with SDK version liferay-plugins-sdk-6.1.1

    Reply
    1. Hi Ashok,

      Currently, I don’t have any code ready. But I will try from my end and let you know or else write separate blog to upload images in liferay and will give you link to follow.

      But I am wondering. Storing images in DB will create performance issues.Instead you can use document library api to store it in document library. Its very easy. Also Admin can manage uploaded images from document library portlet directly.

      Regards
      Nilang

      Reply
    2. Thanks Nilang for the information. I was finally able to upload the images into DB using custom table 🙂 But now i want to display as slide images with description dynamically changing. I meant, if there are 10 images in DB, then all those images should run as slideshow with description changing accordingly in the custom portlet. So now iam finding how to retrieve the List of images and display on the page. Any inputs on how to get the list from DB? Should i use DynamicQuery in this case?

      Reply
    3. Hi Ashok,

      nice to hear you that you are able to save and retrieve images from DB. However, if your purpose it just to set up slideshow with those images, then your approach is not efficient. You can use Web content-structure and template to display slideshow and upload images in Document library which is more efficient and provide greater level of flexibility. Let me know if you need any further help on this.

      Regards
      Nilang

      Reply
  3. Hi Nilang,

    Thanks a lot for your explanation. Really it helped me a lot. I have tried refreshing the project & still could not find those files. Actually i created the service.xml file manually and edited the contents and then ran the ant->build-service command in eclipse to build the jar (service-builder-test-portlet-service.jar) . When i extract the jar file, i could not find those files too. Ok let me try again.

    To elaborate on my requirement, i am trying to create a custom table in existing liferay DB (say such as “customImage” table) wherein i will have imageFile (blob) and imageDescription (String) as columns so that i could insert first and then retrieve the content on view.jsp page. So as said i am trying to create this table using the above steps as mentioned in your blog. Am i in the right direction? Or is there any alternative for doing this in liferay? Kindly let me know.

    Reply
    1. Hi Ashok,

      You are on right direction. To be safer side, just delete all generated files / java classes by service builder,JAR file under portlet/lib folder ,sql script (under service folder under WEB-INF) from the project. Then re build service. Let me know if you still face any trouble by following it.

      Regards
      Nilang

      Reply
    2. Hi Nilang,

      I was finally able to insert images into DB using custom table. In my case it was “PhotoImg” table with columns such as photoname (String), description (String), data (blob). Now i want to retrieve the content from DB, how to go about it? Iam using DynamicQuery like this, but it is not working.

      DynamicQuery dq = DynamicQueryFactoryUtil.forClass(PhotoImg.class). addOrder(OrderFactoryUtil.desc(“photoname”));

      Can you please point me how to retrieve the image and image contents using jsp ?

      Reply
  4. Hi Nilang,

    Thanks for all the steps mentioned for creating service layer. As pointed out by other person, i have a small query wrt classes built when i run ant build-service. I do not get these files either on local system (WEB-INF) or eclipse.
    1. StudentLocalService.java
    2. StudentLocalServiceImpl.java
    3. StudentLocalServiceBaseImpl.java
    4. StudentLocalServiceUtil.java

    Am i missing out anything? Also afterr the ant build, i can see that the service-builder-test-portlet-service.jar generated under WEB_INF/lib folder. So how to proceed after this step? When will the table creation happen after this step (table education_student) ? I am new to liferay development, please help me.

    Reply
    1. Hi Ashok,

      First of all welcome to Tech blog and thanks for appreciations. The above said classed will be generated in respective folder, I mentioned in image no 6 (Starting form top). You need to refresh the project after service build. You can also verify from File system.
      Liferay service builder will create service JAR which will be used to access service layer. When we build service, it will only generate tables SQL. Actual tables will be generated once we deploy the portelt first time after running service builder. Let me know if you need more information. I am planning to write separate blog soon on how to perform actual CRUD operation to save / update /delete data from page to DB. so stay tuned.

      Feel free to ask questions / give suggestion.

      Regards
      Nilang

      Reply
  5. Hi Nilang,

    Your blogs are excellent. I dont think we can find any cleaner approach than this to explain writing code in liferay.
    I recently started learning liferay and the requirement is to integrate it with Broadleaf (open source ecommerce framework). After much struggle i was able to place broadleaf related jars in a portlet and start the application without any exception.But the problem is that I need to use services created in Broadleaf in this portlet. The service i use in portlet always seems to be null no matter how ever I try to inject them.

    Can you please post an example to show how to autowire/inject services available through jars in Spring MVC Portlet? Thanks in advance

    Reply
    1. Hi Anand,

      Thanks for appreciation. The scenario you mentioned, I assume that you are putting Broadleaf’s JAR under lib folder of your portlet. If that JAR contains util class, it can be directly accessed from portlet class itself.

      There is one more alternative for this. You can create liferay service builder. Refer my blog http://www.opensource-techblog.com/2013/03/creating-service-layer-in-service.html for the same. You can then create custom method in your XXXLocalServiceImpl class from where you can make call to Broadleaf’s Service.

      If you need to access this JAR from more than one portlet, then you need to put those jars under / lib folder from where its accessible to all portlet / plugin.

      You many need to point those jars in class path so that it won’t give any error while compiling portlet.

      Let me know if you need any further assistance.

      Regards
      Nilang

      Reply
  6. Hi Nilang,

    I am new to Liferay i am referring all your blogs they are very very helpful for me.
    please write one another blog on Form Portlet Development and View Portlet Development.

    Reply
  7. Hi Nilang,

    It seems you can put service.xml in the source code inside the package of your part, thus you can have many service.xml inside the same project !

    Sylvain

    Reply
  8. Hi Nilang I am trying to study Liferay and with this example I am not sure on how to see the client side form that will try to get all the service working like an example of actual adding of Student from the JSP page to the Service Layer

    Thanks
    jj

    Reply
    1. Hi Jarin,

      Thanks for appreciation and welcome to Tech blog. I am planning to write separate blog called CRUD operation in Liferay with Service Builder. I am sure you will get all what you are searching for from next blog. I will let you know once its done.

      Regards
      Nilang

      Reply
  9. Hi Nilang,

    Very good posts and very helpful in learning liferay.

    I have a question,
    I’m getting error”CreateProcess error=206, The filename or extension is too long” when i run the “ant build-service” command.I tried to shorten the name but still the problem persists.
    Is there any alternate way to generate the entity classes, or how can we achieve the same using maven tools.

    Thanks & Regards,
    Ashwin

    Reply
    1. Hi Ashwin.

      Thanks for appreciation and welcome to Tech blog. Can you please check whether you placed your plugin SDK under too long folder hieracthy. Ex. D:/Folder1/Folder2/Folder3/Folder4…../Folder20/Plugin-sdk. There is limitation of window os to put the restriction of folder hierarchy after certain limit.

      You can recheck by putting plugin SDK just under drive (ex. d:/plugin-sdk) and re-build the potlet.

      Regards
      Nilang I Patel

      Reply
  10. ServiceBuilder could be very useful, but how can we generate services and entities in differents packages ?
    isn’t aware about “package” attribute from children imports…

    Best regards,
    Sylvain

    Reply
    1. Hi Sylvain,

      Thanks for writing to Tech blog. I understand that you wanted to know how to write different entities in different pacakge ?

      The answer to this is, you can enter more that one entities in single package. Package is nothing but the generated Java package after the service get build.

      Liferay service builder is designed to create one service xml file per portlet. (If they are in different plugin project). And hence you can add multiple entities under single pacakge. If you need to change the package, you need to create new service.xml file in different portlet.

      Feel free to ask questions / give feedback

      Regards
      Nilang

      Reply
  11. hey Nilang

    Thanks for all ur blogs.
    i have a small question while following these steps i am not being able to see following classes after building the project-
    1. StudentLocalService.java
    2. StudentLocalServiceImpl.java
    3. StudentLocalServiceBaseImpl.java
    4. StudentLocalServiceUtil.java

    Infact i cant see src folder inside /WEB-INF location.

    I want know if i have missed some step to follow or if it’s something else.

    Reply
    1. Hi Gaurav,

      Thanks for appreciation and welcome to Tech blog. Actually those classes will be inside service JAR file located under WEB-INF/lib folder.

      Also if you are using eclipse then by default the src folder will be shown as Java source in eclipse. If you see actual file system, you will observe that the src folder will be under WEB-INF folder.

      Let me know if you have any other queries
      Regards
      Nilang

      Reply
    1. Hi Gulam,

      First of all welcome to Tech blog. For this blog, you can refer the thing what I have mentioned and all the code will be generating by liferay service builder. I can definitely put the source code, but for this blog, you can better understand the code if you follow all the steps mentioned here.

      Regards
      Nilang I Patel

      Reply
    1. Hi Narnar,

      I can give steps to achieve this. As per my blog, we need to user XXXLocalServiceUtil class for any CRUD operation. So you can do one thing. You can call this method in controller, get the list of models and pass to JSP. In JSP you can put the loop and from each model, you can show its attribute from its property.

      Let me know if this is sufficient for you. If you feel difficulty, let me know I will create sample application and will share it with you.

      Regards
      Nilang I Patel

      Reply
  12. Hi Danish,

    Thanks for appreciation. Sure I am going to write approx 5-6 other blogs related to Service builder which covers most of the things that required in day to day development.

    Regards
    Nilang

    Reply

Post Comment