• CRUD Operations in Liferay Portlet

    Posted on May 5, 2015 by Hamidul Islam in Liferay.

    crud-operations-in-liferay


    aimIn this article we will explain how to perform CRUD Operations in Liferay Custom Portlet. We will also explain the how to use service builder tool to perform all the operations one by one. Many new comers find difficulty to use liferay service builder tool to perform CRUD Operations in Liferay portlet.  So this article will be helpful for them. However for experienced liferay developer this article would be helpful with respect to security concern.At the end of this article we will understand how to perform Create, Read, Update and Delete Operations on Liferay Entity. 


    1. Create a basic portlet

    At first we need a basic portlet project. We are not going to explain how to create a portlet. Consider that our portlet project name is crud-example-portlet

    portlet-project

    2. Create a service.xml file under WEB-INF as shown in the above. The content of the file is

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.2.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_2_0.dtd">
    <service-builder package-path="com.proliferay.sbuilder.example.crud">
    	<author>Hamidul Islam</author>
    	<namespace>Crud</namespace>
    	<entity name="Book" table="CRUD_BOOK_PORTLET" local-service="true" remote-service="true">
    		<column name="bookId" type="long" primary="true" id-type="increment"/>
    		<column name="bookName" type="String" />
    		<column name="description" type="String" />
    		<column name="authorName" type="String" />
    		<column name="isbn" type="int" />
    		<column name="price" type="int" />
    	</entity>
    </service-builder>
    

    Note 1: Book is the entity name. It represents the database table. Once service is generated, lots of code will be generated based entity name. For example Book.java, BookLocalServiceImpl.java, BookServiceImpl.java etc. Book.java will be a model class. All the setter and getter methods will be generated like setBookName,getBookName, setDescription, getDescription etc. 

    Note 2:  table="CRUD_BOOK_PORTLET" means that book information will be saved in CRUD_BOOK_PORTLET table. 

    Note 3:  id-type="increment" means that each time we create a new row of book, one incremented primary key will be generated.

    Note 4: local-service and remote-service are set true. This means that BookLocalServiceImpl.java and BookServiceImpl.java files will be generated after building our service. By default Both the files will be empty. However we can write our own custom methods in those files. The methods of BookLocalServiceImpl.java can be called only from local machine and on the other hand methods of BookServiceImpl.java can be called remotely. 

    Note 5: Column represents simply columns of the table. The type of the column is defined by type attribute. 

    3. Building service

    If you properly configured your liferay with Liferay IDE then build the service as shown in below. We can also run build service by running ant build-service.

    build-service

    4.Identify 4 methods for all the operations

    If the build service is successful then all the service methods will be created for all the operations like Create, Read, Update and Delete. We just need to call the correct methods. Have a look in service.xml file. The entity name is Book. After building the service along with other files BookLocalServiceUtil.java will be generated. This class contains all the methods to perform CRUD operations in liferay portlet.

    i) To create, BookLocalServiceUtil.addBook(book)

    ii) For reading, BookLocalServiceUtil.getBook(bookId)

    iii) For updating, BookLocalServiceUtil.updateBook(book)

    iv) To delete, BookLocalServiceUtil.deleteBook(bookId)

    All these methods will be created by default. 

    5. Portlet class

    All the 4 operations are written in portlet class. The whole portlet class code is given below 

    package com.proliferay.portlet;
    
    import javax.portlet.ActionRequest;
    import javax.portlet.ActionResponse;
    import javax.portlet.PortletSession;
    import javax.portlet.ProcessAction;
    
    import com.liferay.portal.kernel.exception.PortalException;
    import com.liferay.portal.kernel.exception.SystemException;
    import com.liferay.portal.kernel.log.Log;
    import com.liferay.portal.kernel.log.LogFactoryUtil;
    import com.liferay.portal.kernel.servlet.SessionMessages;
    import com.liferay.portal.kernel.util.ParamUtil;
    import com.liferay.util.bridges.mvc.MVCPortlet;
    import com.proliferay.sbuilder.example.crud.model.Book;
    import com.proliferay.sbuilder.example.crud.service.BookLocalServiceUtil;
    import com.proliferay.util.ActionUtil;
    import com.proliferay.util.WebKeys;
    
    /**
     *
     * @author Hamidul Islam
     *
     */
    
    public class BookPortlet extends MVCPortlet{
    
    	/**
    	 *
    	 * This method will persist the data in database
    	 */
    	@ProcessAction(name = "addBook")
    	public void addBook(ActionRequest actionRequest,ActionResponse actionResponse) throws SystemException {
    		Book book = ActionUtil.bookFromRequest(actionRequest);
    
    		//Calling service method to persist book.
    		BookLocalServiceUtil.addBook(book);
    		SessionMessages.add(actionRequest, "added-book");
    	   _log.info("#################Added Book Successfully#########################");
    	}
    
    	@ProcessAction(name = "deleteBook")
    	public void deleteBook(ActionRequest actionRequest,ActionResponse actionResponse) throws SystemException, PortalException {
    		long bookId = ParamUtil.getLong(actionRequest, "bookId");
    		BookLocalServiceUtil.deleteBook(bookId);
    		SessionMessages.add(actionRequest, "deleted-book");
    		_log.info("#################Book Deleted Successfully#########################");
    	}
    
    	@ProcessAction(name = "viewBook")
    	public void viewBook(ActionRequest actionRequest,ActionResponse actionResponse) throws SystemException, PortalException {
    		long bookId = ParamUtil.getLong(actionRequest, "bookId");
    		Book book = BookLocalServiceUtil.getBook(bookId);
    		actionRequest.setAttribute(WebKeys.BOOK_ENTRY, book);
    		//Show view_book.jsp
    		actionResponse.setRenderParameter("jspPage", "/html/view_book.jsp");
    	}
    
    	@ProcessAction(name = "updateBook")
    	public void updateBook(ActionRequest actionRequest,ActionResponse actionResponse) throws SystemException, PortalException {
    		long bookId = (Long) actionRequest.getPortletSession().getAttribute(WebKeys.BOOK_ID,PortletSession.PORTLET_SCOPE);
    		Book book = ActionUtil.bookFromRequest(actionRequest);
    		book.setBookId(bookId);
    		/**
    		 * Calling service method to update book.
    		 * While calling update method we must have primary key in the passing object.
    		 */
    		BookLocalServiceUtil.updateBook(book);
    		SessionMessages.add(actionRequest, "updated-book");
    		_log.info("#################Updated Book Successfully#########################");
    
    	}
    
    	@ProcessAction(name = "viewEdit")
    	public void viewEdit(ActionRequest actionRequest,ActionResponse actionResponse) throws SystemException, PortalException {
    		long bookId = ParamUtil.getLong(actionRequest, "bookId",0);
    		Book book = BookLocalServiceUtil.getBook(bookId);
    		actionRequest.setAttribute(WebKeys.BOOK, book);
    		//Show edit_book.jsp
    		actionResponse.setRenderParameter("jspPage", "/html/edit_book.jsp");
    		actionRequest.getPortletSession().setAttribute(WebKeys.BOOK_ID, book.getBookId(),PortletSession.PORTLET_SCOPE);
    
    	}
    	private Log _log = LogFactoryUtil.getLog(BookPortlet.class.getName());
    
    }
    

    Note 1: For updating a record in database we must need primary key. While updating book the primary key of the book is kept in portlet session and retrieved from the portlet session just before updating book. Many developers keep the primary key in hidden filed which is not good practice with respect to security concern.  

    Note 2: Download whole source code for better understanding. 

    Download Source Code

2 Responses so far.

  1. alok says:

    Very Nice ,Completed successfully .
    Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

Are you human? * Time limit is exhausted. Please reload CAPTCHA.

Top
%d bloggers like this:

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close