Hello Everybody,

I am trying to deploy a jpa application on karaf-3.0.2-SNAPSHOT as a
feature.

Currently, I have the following bundles.

1. domain-bundle (all jpa entites + persistence/orm.xml)
2. a service bundle where the entity manager is injected into this service
via blueprint.
3. a rest service bundle (using camel cxfrs) where the service method is
fired as a bean method  
    invocation.
4. hibernate as the orm framework (4.3.6.Final).

All the above bundles are wrapped under one feature.

The entrypoint to the application is the rest interface which in turn
delegates the call to a camel route and from there the service method is
fired and inside the service bundle, using the entitymanager, I persist the
data into the database.

Everything works well. The problem however is that, when I make a change to
any of the above 4 four bundles, I try to uninstall the feature and install
the feature again (I guess there is no feature:update for now.).

After uninstalling and installing the feature, when I try to invoke the rest
service, it complains with the error: Caused by:
java.lang.IllegalArgumentException: object is not an instance of declaring
class

But, after uninstalling / installing the feature, if I restart karaf,
everything works.

The details of each of the bundles are provided below for reference.

Persistence.xml (domain bundle)
=====================

<persistence-unit name="test" transaction-type="JTA">
<jta-data-source>
        
osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/testds)
</jta-data-source>
<properties>
        <property name="hibernate.hbm2ddl.auto" value="create-drop"></property>
        <property name="hibernate.show_sql" value="true"/>
        <property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>

Service Bundle (blueprint)
================

<bean id="testBean" class="org.test.TestServiceImpl">
                <jpa:context unitname="test" property="entityManager" />
                <tx:transaction method="*" value="Required" />
                <property name="testServiceB" ref="refServiceB"></property>
        </bean>

        <service ref="testBean" interface="org.test.api.TestService1Api" 
activation="lazy" />
        
        <reference id="refServiceB"
             interface="org.test.api.TestService2Api" activation="lazy"/>

</bean>

Rest Services Bundle (blueprint)
====================

<camel:camelContext id="testContext">
                <camel:package>org.test.rest.routes</camel:package>     
</camel:camelContext>

<reference id="testServiceA"
             interface="org.test.api.TestService1Api" activation="eager" />

<cxf:rsServer id="test" address="/test/rest"
                serviceClass="org.test.rest.impl.TestRestImpl"
                loggingFeatureEnabled="true" loggingSizeLimit="20">
                <cxf:providers>
                        <ref component-id="jsonProvider" />
                </cxf:providers>
                <cxf:extensionMappings>
                        <entry key="json" value="application/json" />
                        <entry key="xml" value="application/xml" />
                </cxf:extensionMappings>
</cxf:rsServer>

<bean id="jsonProvider"
class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider">
                <property name="mapper" ref="jacksonMapper" />
</bean>

<bean id="jacksonMapper"
        class="org.test.rest.utils.CustomJacksonObjectMapper" />

Camel Route: (java dsl):
===============

from("cxfrs:bean:test?bindingStyle=SimpleConsumer").routeId("xyz")
        .to("log://{camelLogger?level=INFO")
        .recipientList(simple("direct:${header.operationName}"));
                
from("direct:testMethod1").to("log://camelLogger?level=INFO")
        .to("bean:testServiceA?method=serviceMethod1")
        .to("log://camelLogger?level=INFO");

Datasource Configuration: (blueprint)
=======================

 <bean id="dataSource" class="org.postgresql.ds.PGPoolingDataSource"
destroy-method="close">
      <property name="serverName" value="localhost"/>
      <property name="databaseName" value="test"/>
      <property name="portNumber" value="5433"/>
      <property name="user" value="test"/>
      <property name="password" value="test"/>
      <property name="dataSourceName" value="testds"/>
      <property name="initialConnections" value="2"/>
      <property name="maxConnections" value="4" />
  </bean>
  
  <service interface="javax.sql.DataSource" ref="dataSource">
    <service-properties>
            <entry key="osgi.jndi.service.name" value="jdbc/testds"/>
    </service-properties>
  </service>

Feature xml: 
===========

<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0";
name="test-features">
    <feature name="test-features" version="1.0.0-SNAPSHOT"
description="test-features" resolver="(obr)">
        <bundle
start-level="60">mvn:org.test/test-servicea/1.0.0-SNAPSHOT</bundle>
        <bundle
start-level="60">mvn:org.test/test-model/1.0.0-SNAPSHOT</bundle>
        <bundle
start-level="60">mvn:org.test/test-serviceb/1.0.0-SNAPSHOT</bundle>
        <bundle
start-level="60">mvn:org.test/test-rest-service/1.0.0-SNAPSHOT</bundle>
    </feature>
</features>

Hibernate Exception: (after feature uninstall / install)
=================================

Caused by: org.hibernate.PropertyAccessException: IllegalArgumentException
occurred calling getter of org.test.model.EntityA.id
        at
org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:192)
        at
org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:346)
        at
org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4746)
        at
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:164)
        at
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85)
        at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876)
        at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858)
        at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863)
        at
org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196)
        ... 86 more
Caused by: java.lang.IllegalArgumentException: object is not an instance of
declaring class
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native 
Method)[:1.8.0_05]
        at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)[:1.8.0_05]
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_05]
        at java.lang.reflect.Method.invoke(Method.java:483)[:1.8.0_05]
        at
org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:169)
        ... 94 more

Could it be a classloader issue when the feature is uninstalled and
installed again, the classes are loaded in a different class loader and
somewhere the original classes loaded via a different class loader is being
referenced? Just a wild guess.

And this happens at the time of merging the entity into the database. I use 
 T entityManager.merge(T entity)

Hibernate here might be checking if the passed entity is an instance of
class T. Here is where I doubt that the hibernate entity manager's class
loader and the service class loader are referencing different versions of
the domain bundle via different class loaders.

Can somebody tell me where am I going wrong?

Thanks in advance.

best regards
Sriraman.




--
View this message in context: 
http://karaf.922171.n3.nabble.com/karaf-jpa-hibernate-error-updating-bundles-via-feature-uninstall-feature-install-tp4034887.html
Sent from the Karaf - User mailing list archive at Nabble.com.

Reply via email to