При работе с Liferay service builder часто возникает необходимость работы с несколькими базами данных. Например, хорошей практикой считается держать таблицы, используемые самим порталом в одной базе, а таблицы с данными для приложения в другой. Также иногда приходится работать с несколькими наборами таблицам, находящихся в различных базах. Эта задача модет быть решена следующим образом:
1. Нужно добавить конфигурацию для подключения к бд в portal-ext.properties. В моем случае это выглядело следующим образом:
jdbc.newDbConfig.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.newDbConfig.url=...
jdbc.newDbConfig.username=...
jdbc.newDbConfig.password=...
jdbc.newDbConfig.maxIdleTimeExcessConnections=60
jdbc.newDbConfig.minPoolSize=5
jdbc.newDbConfig.maxPoolSize=10
jdbc.newDbConfig.maxActive=10
jdbc.newDbConfig.acquireIncrement=5
После внесения изменений в portal-ext.properties необходимо перезапустить сервер. Вместо newDbConfig можно дать свое название для конфигурации подключения. Это название будет использоваться в следующем шаге.
2. Необходимо создать файл ext-spring.xml и поместить его в src/META-INF
<?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">
<bean id="newHibernateSessionFactory" class="com.liferay.portal.kernel.spring.util.SpringFactoryUtil"
factory-method="newBean">
<constructor-arg
value="com.liferay.portal.spring.hibernate.PortletHibernateConfiguration" />
<constructor-arg>
<map>
<entry key="dataSource" value-ref="newDataSource" />
</map>
</constructor-arg>
</bean>
<bean id="newSessionFactory" class="com.liferay.portal.kernel.spring.util.SpringFactoryUtil"
factory-method="newBean">
<constructor-arg
value="com.liferay.portal.dao.orm.hibernate.PortletSessionFactoryImpl" />
<constructor-arg>
<map>
<entry key="dataSource" value-ref="newDataSource" />
<entry key="sessionFactoryClassLoader" value-ref="portletClassLoader" />
<entry key="sessionFactoryImplementor" value-ref="newHibernateSessionFactory" />
</map>
</constructor-arg>
</bean>
<bean id="newDataSourceImpl"
class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean">
<property name="propertyPrefix" value="jdbc.newDbConfig." />
</bean>
<bean id="newDataSource"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource" ref="newDataSourceWrapper" />
</bean>
<bean id="newDataSourceWrapper" class="com.liferay.portal.dao.jdbc.util.DataSourceWrapper">
<constructor-arg ref="newDataSourceImpl" />
</bean>
<bean class="com.liferay.portal.dao.jdbc.util.DataSourceSwapper">
<property name="liferayDataSourceWrapper" ref="newDataSourceWrapper" />
</bean>
</beans>
Это позволит определить необходимый для работы набор бинов (SessionFactory, DataSource и т.д.).
В свойстве propertyPrefix указывается название конфигурации из portlet-ext.properties.
3. Почти все готово! Остается только в service.xml задать для сущностей необходимый dataSource и SessionFactory. Это делается при помощи атрибутов data-source и session-factory. Названия бинов берутся из ext-spring.xml.
<entity name="EmpDep" local-service="true" remote-service="false"
table="EMP_DEP" cache-enabled="false" data-source="newDataSource" session-factory="newSessionFactory">
<column ... />
...
</entity>