Foren

Service Builder With Custom DataSource Breaks Hot Deploy

Ohad Raz, geändert vor 11 Jahren.

Service Builder With Custom DataSource Breaks Hot Deploy

New Member Beiträge: 23 Beitrittsdatum: 27.06.12 Neueste Beiträge
Hi,

I have created a simple service builder that uses a custom data source.
As a result, the hot-deploy functionality got broken.
When trying to hot-deploy the following exception appears in the server's log:

com.liferay.portal.kernel.exception.SystemException: com.liferay.portal.kernel.dao.orm.ORMException: java.lang.IllegalStateException: The com.liferay.portal.model.impl.CompanyImpl Cache is not alive.
com.liferay.portal.kernel.exception.SystemException: com.liferay.portal.kernel.dao.orm.ORMException: java.lang.IllegalStateException: The com.liferay.portal.model.impl.CompanyImpl Cache is not alive.
at com.liferay.portal.service.persistence.impl.BasePersistenceImpl.processException(BasePersistenceImpl.java:190)
at com.liferay.portal.service.persistence.CompanyPersistenceImpl.fetchByPrimaryKey(CompanyPersistenceImpl.java:488)
at com.liferay.portal.service.persistence.CompanyPersistenceImpl.findByPrimaryKey(CompanyPersistenceImpl.java:432)
at com.liferay.portal.service.impl.CompanyLocalServiceImpl.getCompanyById(CompanyLocalServiceImpl.java:461)
at sun.reflect.GeneratedMethodAccessor219.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
...

(The same exception repeats for all kind of Liferay's objects, not necessary the Company alone, e.g., Layout).

I have built my service builder based on the tips in the following blog:
http://www.liferay.com/about-us/privacy/-/blogs/6831821/maximized
It all seemed to work, but when I tried to hot-deploy, the aforementioned exceptions were observed.

My service.xml looked as follows:
<!--?xml version="1.0" encoding="UTF-8"?-->


<service-builder package-path="com.company.project.entity" auto-namespace-tables="true">
   <author>&lt;a href="ohad.raz@orbitz.com"&gt;Raz, Ohad&lt;/a&gt;</author>

   <namespace>entity</namespace>
   <entity name="Entity" local-service="true" human-name="Entities" table="TB_ENTITY" data-source="company-project-DS" session-factory="company-project-SessionFactory" tx-manager="company-project-TransactionManager">

      <!-- PK fields -->
      <column db-name="TB_ENTITY_ID" name="entityID" primary="true" type="long" />

      <!-- Audit fields -->
      <column db-name="CREATE_DATE" name="createDate" type="Date" />
      <column db-name="MODIFIED_DATE" name="modifiedDate" type="Date" />

      <!-- Other fields -->
      <column db-name="COLUMN_A" name="columnA" type="long" />
      <column db-name="COLUMN_B" name="columnB" type="String" />
      <column db-name="COLUMN_C" name="columnC" type="Date" />

      <!-- Finder methods -->
      <finder name="ColumnA" return-type="Entity">
         <finder-column name="columnA" />
      </finder>
   </entity>
</service-builder>

And my ext-spring.xml looked as follows:
<!--?xml version="1.0" encoding="UTF-8"?-->

<beans 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="company-project-SessionFactory" class="com.liferay.portal.dao.orm.hibernate.SessionFactoryImpl" lazy-init="true">
      <property name="sessionFactoryImplementor">
         <bean class="com.liferay.portal.spring.hibernate.PortalHibernateConfiguration" lazy-init="true">
            <property name="dataSource">
               <ref bean="company-project-DS" />
            </property>
            <property name="mappingResources">
               <list>
                  <value>META-INF/portlet-hbm.xml</value>
               </list>
            </property>
         </bean>
      </property>
   </bean>

   <bean id="company-project-DS" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy" lazy-init="true">
      <property name="targetDataSource">
         <bean class="com.liferay.portal.spring.jndi.JndiObjectFactoryBean" lazy-init="true">
            <property name="jndiName">
               <value>jdbc/CompanyProjectData</value>
            </property>
         </bean>
      </property>
   </bean>

   <bean id="company-projec-TransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" lazy-init="true">
      <property name="dataSource">
         <ref bean="company-projec-DS" />
      </property>
      <property name="sessionFactory">
         <ref bean="company-projec-SessionFactory" />
      </property>
   </bean>
</beans>


So, where was the problem?
Ohad Raz, geändert vor 11 Jahren.

RE: Service Builder With Custom DataSource Breaks Hot Deploy (Antwort)

New Member Beiträge: 23 Beitrittsdatum: 27.06.12 Neueste Beiträge
So, I have came across the following thread:
http://www.liferay.com/community/forums/-/message_boards/message/13076583
which, in its turn, points to http://www.liferay.com/community/forums/-/message_boards/message/10713975.
So I realized that the problem is that I have used com.liferay.portal.spring.hibernate.PortalHibernateConfiguration as the Session Factory Implementor.
I looked at the source code of this class, and indeed it seems to be messing Liferay's internals, and should be used for custom data sources and entities.
So, I tried the suggestions in the aforementioned thread, using org.springframework.orm.hibernate3.LocalSessionFactoryBean as the Session Factory Implementor.
But then I kept getting org.hibernate.HibernateException: Unable to get the default Bean Validation factory exception.
I googled it, and found that I had to add a hibernate-validator.jar to my classpath.
I have tried several jars, of different versions, but nothing helped.
I finally found the properties needed to disable the validator, but then I got exceptions about cache - either enabling, it, or missing provider...
Another google, and...
Eureka!
It all works! Liferay starts up with no exceptions, it runs fine, and I can hot-deploy!!!

What's changed?

Well, this is the ext-spring.xml that made it all to work:
<!--?xml version="1.0" encoding="UTF-8"?-->
<beans 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="company-project-SessionFactory" class="com.liferay.portal.dao.orm.hibernate.SessionFactoryImpl" lazy-init="true">
      <property name="sessionFactoryImplementor">
         <bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" lazy-init="true">
            <property name="configurationClass">
               <value>org.hibernate.cfg.Configuration</value>
            </property>
            <property name="dataSource">
               <ref bean="company-project-DS" />
            </property>
            <property name="mappingResources">
               <list>
                  <value>META-INF/portlet-hbm.xml</value>
               </list>
            </property>
            <property name="hibernateProperties">
               <props>
                  <prop key="hibernate.validator.apply_to_ddl">false</prop>
                  <prop key="hibernate.validator.autoregister_listeners">false</prop>
                  <prop key="javax.persistence.validation.mode">none</prop>
                  <prop key="hibernate.cache.use_second_level_cache">true</prop>
                  <prop key="hibernate.cache.use_query_cache">true</prop>
                  <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
               </props>
            </property>
         </bean>
      </property>
   </bean>

   <bean id="company-project-DS" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy" lazy-init="true">
      <property name="targetDataSource">
         <bean class="com.liferay.portal.spring.jndi.JndiObjectFactoryBean" lazy-init="true">
            <property name="jndiName">
               <value>jdbc/CompanyProjectData</value>
            </property>
         </bean>
      </property>
   </bean>

   <bean id="company-project-TransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" lazy-init="true">
      <property name="dataSource">
         <ref bean="company-project-DS" />
      </property>
      <property name="sessionFactory">
         <ref bean="company-project-SessionFactory" />
      </property>
   </bean>
</beans>


Hope it can help anyone encountering the same problems...

Cheers,
Ohad
thumbnail
David H Nebinger, geändert vor 11 Jahren.

RE: Service Builder With Custom DataSource Breaks Hot Deploy

Liferay Legend Beiträge: 14916 Beitrittsdatum: 02.09.06 Neueste Beiträge
Not sure what you've used, but here's how I define external db connections...


 <bean id="myDataSource" lazy-init="true" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    ....
 </bean>
 <bean id="myHibernateSessionFactory" class="com.liferay.portal.spring.hibernate.PortletHibernateConfiguration">
    <property name="dataSource" ref="myDataSource" />
    ....
 </bean>
 <bean id="mySessionFactory" class="com.liferay.portal.dao.orm.hibernate.PortletSessionFactoryImpl">
    <property name="dataSource" ref="myDataSource" />
    <property name="sessionFactoryClassLoader" ref="portletClassLoader" />
    <property name="sessionFactoryImplementor" ref="myHibernateSessionFactory" />
 </bean>


This way I'm still using all Liferay entities (don't know if it's necessary, but maximizes compatibility).

Also I don't need to define anything for transaction handling (the default Liferay transaction handling has been good enough).

As far as hibernate validator was concerned, I too had to add it, but version 4.3.0 worked just fine. Needed the hibernate-validator-4.3.0.Final.jar and hibernate-validator-annotation-processor-4.3.0.Final.jar in my lib folder, but had no version issues to deal with.

And I didn't have to disable the cache!
thumbnail
Konstantin Chudinov, geändert vor 10 Jahren.

RE: Service Builder With Custom DataSource Breaks Hot Deploy

Junior Member Beiträge: 43 Beitrittsdatum: 23.04.13 Neueste Beiträge
I have the same issue! But in my case, everything is not so simpleemoticon
I also used this awrful blog:
http://www.liferay.com/about-us/privacy/-/blogs/6831821/maximized
It's stale!
Don't use it!
In my case liferay don't see
<property name="mappingResources">
<list>
<value>META-INF/portlet-hbm.xml</value>
</list>
</property>

I deleted these strings and I cought error with hibernate sql. i dont inderstand the reason, and I don't want to! I have small time to solve this problem and I spent the whole day for it.

DO SOMEBODY HAS COMPLETE WORKING EXAMPLE FOR LIFERAY 6.1 for connecting to external DB???
thumbnail
Francis Franco Freich, geändert vor 10 Jahren.

RE: Service Builder With Custom DataSource Breaks Hot Deploy

New Member Beiträge: 10 Beitrittsdatum: 17.05.11 Neueste Beiträge
Konstantin Chudinov:
I have the same issue! But in my case, everything is not so simpleemoticon
I also used this awrful blog:
http://www.liferay.com/about-us/privacy/-/blogs/6831821/maximized
It's stale!
Don't use it!
In my case liferay don't see
<property name="mappingResources">
<list>
<value>META-INF/portlet-hbm.xml</value>
</list>
</property>

I deleted these strings and I cought error with hibernate sql. i dont inderstand the reason, and I don't want to! I have small time to solve this problem and I spent the whole day for it.

DO SOMEBODY HAS COMPLETE WORKING EXAMPLE FOR LIFERAY 6.1 for connecting to external DB???


Are you tied to particular technologies? Other than Liferay of course.
Harry Mark, geändert vor 10 Jahren.

RE: Service Builder With Custom DataSource Breaks Hot Deploy

New Member Beitrag: 1 Beitrittsdatum: 06.10.10 Neueste Beiträge
To get it working I searched hibernate-spring.xml (in Liferay source) for bean definitions that reference "liferayDataSource". Copied the definitions and renamed them, changing some of the properties for the portlet. Note: jdbc/ExternalPool is a global Tomcat data source.

Here's the ext-spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans 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="externalDataSource" class="com.liferay.portal.spring.jndi.JndiObjectFactoryBean" lazy-init="true">
<property name="jndiName">
<value>jdbc/ExternalPool</value>
</property>
</bean>

<bean id="externalHibernateSessionFactory" class="com.liferay.portal.spring.hibernate.PortalHibernateConfiguration">
<property name="dataSource" ref="externalDataSource" />
<property name="mappingResources">
<list>
<value>/META-INF/portlet-hbm.xml</value>
</list>
</property>
</bean>

<bean id="externalSessionFactory" class="com.liferay.portal.dao.orm.hibernate.SessionFactoryImpl">
<property name="sessionFactoryClassLoader" ref="portletClassLoader" />
<property name="sessionFactoryImplementor" ref="externalHibernateSessionFactory" />
</bean>

<bean id="externalTransactionManager" class="com.liferay.portal.spring.transaction.TransactionManagerFactory" factory-method="createTransactionManager">
<constructor-arg ref="externalDataSource" />
<constructor-arg ref="externalHibernateSessionFactory" />
</bean>
</beans>


To use the external data source in service.xml objects, you need to set the data-source, session-factory & tx-manager attributes to these bean IDs. Run the "build-service" target then "deploy":

<entity name="Student" local-service="true" remote-service="false" data-source="externalDataSource" session-factory="externalSessionFactory" tx-manager="externalTransactionManager">
....


Note that the corresponding database objects must already exist in the external DB.