Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Liferay's service builder to access existing tables in the database

Tags:

liferay

I am writing a portlet that needs to read from a set of tables in the liferay database created by a different service builder portlet.

I tried just duplicating the service.xml and building the service and all I get for my troubles is :

BeanLocator has not been set

Is there a simple way of writing a second portlet that can get to these existing tables and can service builder be configured to do this rather than trying to re-create what is already there?

I do not want to add this into the original portlet if at all possible as these tables are holding information that a variety of other portlets may need to access and having a vast number of portlets in one deployment will make maintenance a headache.

like image 783
Paul Gilfedder Avatar asked Mar 05 '12 16:03

Paul Gilfedder


People also ask

Can we set multiple databases with Liferay Portal?

Yes, you can't have 2 databases configured in one portal-ext. properties. You need to define a datasource in your service.


1 Answers

For accessing the same tables of a service in different portlets, do not recreate the services in each one. Instead, create the service in one portlet and copy its docroot/WEB-INF/lib/<pluginmame>-portlet-service.jar to the docroot/WEB-INF/lib/ directory of the other portlets. Let us see an example.

Suppose you have the following service.xml in a portlet called person-portlet:

<service-builder package-path="br.com.seatecnologia.stackoverflow.person">
    <author>brandizzi</author>
    <namespace>StackOverflowPerson</namespace>

    <entity name="Person" local-service="true" remote-service="false">
        <column name="personId" type="long" primary="true" />

        <column name="name" type="String" />
        <column name="age" type="int" />
    </entity>
</service-builder>

You generate the services and use it in the original portlet, as usual. For example, you can create a JSP with a form for person registration and person listing:

<%@page import="br.com.seatecnologia.stackoverflow.person.service.PersonLocalServiceUtil"%>
<%@page import="br.com.seatecnologia.stackoverflow.person.model.Person"%>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>

<portlet:actionURL name="addPerson" var="url" />

<aui:form action="<%= url %>" name="fm" method="POST">
<aui:fieldset>
<aui:input name="name" />
<aui:input name="age" />
<aui:button type="submit" />
</aui:fieldset>
</aui:form>

<ul>
    <% for (Person person : PersonLocalServiceUtil.getPersons(-1, -1)) { %>
    <li><%= person.getName() %> : <%= person.getAge() %></li>
    <% } %>
</ul>

Now, suppose you need another portlet, some kind of Hello World which presents a greeting message to all registered persons. You create a new portlet plugin - called, let us say, multiple-hello-portlet - and then copies the file person-portlet-service.jar from the person-portlet/docroot/WEB-INF/lib directory to multiple-hello-portlet/docroot/WEB-INF/lib. If you have both portlets deployed in the same portal_, you can use the services created for person-portlet in the multiple-hello-portlet too. For example, your multiple-hello-portlet can have the following JSP and there is no need of reimplementing services:

<%@page import="br.com.seatecnologia.stackoverflow.person.service.PersonLocalServiceUtil"%>
<%@page import="br.com.seatecnologia.stackoverflow.person.model.Person"%>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>

<% for (Person person :  PersonLocalServiceUtil.getPersons(-1, -1)) { %>
    <div class="portlet-msg-info">
        Hello, <%= person.getName() %>!
        You are <%= person.getAge() %> years old.
    </div>
<% } %>

I created two runnable portlets with these examples, that you can find in BitBucket.

like image 143
brandizzi Avatar answered Sep 28 '22 08:09

brandizzi