Wednesday 22 May 2013

Connection Pool in Service Builder Code that refers to a different DB: Liferay

Introduction:-

In this tutorial we are gonna learn - how to create a datasource that refers to a different DB(ie. other than our liferay DB) and provide custom connection pooling  values. However, Liferay has provided inbuilt connection pooling but we cannot manipulate or modify the max pool size etc and other values, when needed. So, here is the solution.

Steps:-
1. Create a new portlet.(as in here)
2. Create service.xml(as in here)
3. In /{my-portlet}/docroot/WEB-INF/src/META-INF create a file ext-spring.xml
<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    default-destroy-method="destroy" default-init-method="afterPropertiesSet"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <!-- placeholder that manage then data source entry from a jdbc.properties
        file from WEB-INF folder -->
    <bean
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>/WEB-INF/jdbc.properties</value>
        </property>
        <property name="placeholderPrefix" value="${jdbc.eportal" />
    </bean>
    <bean id="eportalDBTarget" class="com.liferay.portal.spring.jndi.JndiObjectFactoryBean"
        lazy-init="true">
        <property name="jndiName">
            <value>jdbc/eportalDB</value>
        </property>
    </bean>

    <bean id="eportalDB"
        class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy"
        lazy-init="true">

        <property name="targetDataSource">
            <ref bean="eportalDBTarget" />
        </property>

    </bean>
    <bean id="liferayHibernateSessionFactory"
        class="com.liferay.portal.spring.hibernate.PortletHibernateConfiguration">
        <property name="dataSource" ref="eportalDB" />
    </bean>
    <bean id="liferayTransactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="dataSource" ref="eportalDB" />
        <property name="globalRollbackOnParticipationFailure" value="false" />
        <property name="sessionFactory" ref="liferayHibernateSessionFactory" />
    </bean>
    <bean id="liferaySessionFactory" class="com.liferay.portal.dao.orm.hibernate.SessionFactoryImpl">
        <property name="sessionFactoryImplementor" ref="liferayHibernateSessionFactory" />
    </bean>
</beans>

4. In the web.xml append the following code in <web-app
<resource-ref>
        <res-ref-name>jdbc/eportalDB</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

5. Create a file context.xml with the following code, in {my-portlet}/docroot/META-INF/
<?xml version="1.0" encoding="UTF-8"?>

<Context antiJARLocking="true" antiResourceLocking="true" privileged="true" crossContext="true">
    <Resource name="jdbc/eportalDB" auth="Container" type="javax.sql.DataSource"
        maxActive="100" maxIdle="30" maxWait="10000" username="postgres"
        password="postgres" driverClassName="org.postgresql.Driver"
        url="jdbc:postgresql://localhost:5432/postgres?useUnicode=true" />
</Context>

6. Last but not the least, add the datasource name to your service.xml as in here.
<!--entity-Employee -->
    <entity name="Employee" table="employee" local-service="true"
        remote-service="true" data-source="eportalDB">

        <!-- PK fields -->
        <column name="emp_id" type="String" primary="true" />
        <column name="emp_name" type="String" />

    </entity>

7. Create {my-portlet}/docroot/WEB-INF/jdbc.properties file with the following code
eportal.url=jdbc:postgresql://localhost:5432/postgres
eportal.username=postgres
eportal.driverClass=org.postgresql.Driver
eportal.password=postgres

8. Do ant build-service and then deploy.

Here is all you have to do, to implement connection pooling.

NOTE: After deploying the code, in some versions of liferay it replaces the {my-portlet}/META-INF/context.xml.(check here)
So, I just replaced my version of context.xml in the tomcat/Webapps/{my-portlet}/META-INF/ directory of my tomcat.

No comments:

Post a Comment