Connecting the Data Source Using Spring Beans

Sometimes you want to use a database other than Liferay DXP’s. To do this, its data source must be defined in portal-ext.properties or configured as a JNDI data source on the app server. Here you’ll connect Service Builder to a data source using Spring XML files. This approach only works with Service Builder modules that use the spring dependency injection option. Here are the steps:

  1. Specify your database and a data source name in your service.xml.

  2. Create the database manually.

  3. Define the data source.

  4. Create a Spring bean that points to the data source.

  5. Run Service Builder.

Specify Your Database and a Data Source Name in Your service.xml

In your service.xml file, specify the same arbitrary data source name for all of the entities, a unique table name for each entity, and a database column name for each column. Here’s an example:

<?xml version="1.0"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 7.2.0//EN"
    "http://www.liferay.com/dtd/liferay-service-builder_7_2_0.dtd">

<service-builder dependency-injector="spring" package-path="com.liferay.example" >
    <namespace>TestDB</namespace>
    <entity local-service="true" name="Foo" table="testdata" data-source="extDataSource"
            remote-service="false" uuid="false">
           <column name="id" db-name="id" primary="true" type="long" />
           <column name="foo" db-name="foo" type="String" />
           <column name="bar" db-name="bar" type="long" />
    </entity>
</service-builder>

Note the example’s <entity> tag attributes:

data-source: The liferayDataSource alias ext-spring.xml specifies.

table: Your entity’s database table.

Also note that your entity’s <column>s must have a db-name attribute set to the column name.

Create the Database Manually

Create the database per the database specification in your service.xml.

Next, use portal properties to set your data source.

Define the Data Source

If the application server defines the data source using JNDI, skip this step. Otherwise, specify the data source in a portal-ext.properties file. Distinguish it from Liferay’s default data source by giving it a prefix other than jdbc.default.. This example uses prefix jdbc.ext.:

jdbc.ext.driverClassName=org.mariadb.jdbc.Driver
jdbc.ext.password=userpassword
jdbc.ext.url=jdbc:mariadb://localhost/external?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
jdbc.ext.username=yourusername

Restart your server if you defined your data source using portal properties.

Connect Your Service Builder Module to the Data Source Via a Spring Bean

To do this, create a parent context extension (e.g.,ext-spring.xml) in your *-service module’s src/main/resources/META-INF/spring folder or in your traditional portlet’s WEB-INF/src/META-INF folder. Create this folder if it doesn’t exist already.

Define the following elements:

  1. A data source factory Spring bean for the data source. It’s different based on the type.

    • JNDI: Specify an arbitrary property prefix and prepend the prefix to a JNDI name property key. Here’s an example:
    <bean class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean"
        id="liferayDataSourceFactory">
        <property name="propertyPrefix" value="custom." />
        <property name="properties">
            <props>
                <prop key="custom.jndi.name">jdbc/externalDataSource</prop>
            </props>
        </property>
    </bean>
    
    • Portal Properties: Specify a property prefix that matches the prefix (e.g., jdbc.ext.) you used in portal-ext.properties.
    <bean class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean"
        id="liferayDataSourceFactory">
        <property name="propertyPrefix" value="jdbc.ext." />
    </bean>
    
  2. A Liferay data source bean that refers to the data source factory Spring bean.

  3. An alias for the Liferay data source bean. Name the alias after the data source name you specified in the service.xml.

    Here’s an example ext-spring.xml that points to a JNDI data source:

    <?xml version="1.0"?>
    
    <beans default-destroy-method="destroy" default-init-method="afterPropertiesSet"
       xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
       <!-- To define an external data source, the liferayDataSource Spring bean
           must be overridden. Other default Spring beans like liferaySessionFactory
           and liferayTransactionManager may optionally be overridden.
    
           liferayDataSourceFactory refers to the data source configured on the
           application server. -->
       <bean class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean"
           id="liferayDataSourceFactory">
           <property name="propertyPrefix" value="custom." />
           <property name="properties">
               <props>
                   <prop key="custom.jndi.name">jdbc/externalDataSource</prop>
               </props>
           </property>
       </bean>
    
       <!-- The data source bean refers to the factory to access the data source.
       -->
       <bean
           class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy"
           id="liferayDataSource">
           <property name="targetDataSource" ref="liferayDataSourceFactory" />
       </bean>
    
       <!-- In service.xml, we associated our entity with the extDataSource. To
           associate the extDataSource with our overridden liferayDataSource, we define
           this alias. -->
       <alias alias="extDataSource" name="liferayDataSource" />
    </beans>
    

The liferayDataSourceFactory above refers to a JNDI data source named jdbc/externalDataSource. If the data source is in a portal-ext.properties file, the bean requires only a propertyPrefix property that matches the data source property prefix.

The data source bean liferayDataSource is overridden with one that refers to the liferayDataSourceFactory bean. The override affects this bundle (module or Web Application Bundle) only.

The alias extDataSource refers to the liferayDataSource data source bean.

Run Service Builder

Run Service Builder and deploy your -service module. Now your Service Builder services use the data source. You can use the services in your business logic as you always have regardless of the underlying data source.

Congratulations! You’ve connected Service Builder to your external data source.

Sample Service Builder Application Using External Database via JNDI

Sample Service Builder Application Using External Database via JDBC

Service Builder

Business Logic with Service Builder

« Connecting the Data Source Using a DataSourceProviderMigrating a Service Builder Module from Spring DI to OSGi DS »
Was this article helpful?
0 out of 0 found this helpful