Infinispan/JDBC as Backend for Hibernate Search on Wildfly/JBoss - jdbc

I am trying to configure a JDBC-backed Infinispan cache to act as the backend for my Java EE app making use of Hibernate Search. I am deploying on JBoss EAP 7.0 or Wildfly 10. I have a module, cache container, and persistence.xml configuration that does not give me any errors on startup. In addition, I am able to create JPA objects and have them indexed via Hibernate Search as expected. I am then able to query those objects successfully. However, at no time are the SQL tables created in the database that I have configured as my JDBC data source for the cache container. So, obviously, the search indices only exist in memory and are not persisted across app server restarts. Here is what I have done thus far:
Downloaded the Infinispan 8.1.x release that corresponds to the Infinispan release embedded within JBoss EAP. This was done because the hibernate-search modules from Infinispan are not included in the embedded module
I've configured the appropriate modules for the Infinispan hibernate-search module within JBoss EAP
Modified my standalone-full-ha.xml JBoss EAP configuration file to include a JDBC-backed cache-container and cache definitions
Modified my persistence.xml file to make use of an Infinispan cache manager and directory provider
Here is the definition for my cache-container as found in standalone-full-ha.xml:
<cache-container name="hibernateSearch" default-cache="LuceneIndexesData" module="org.infinispan.cachestore.jdbc" jndi-name="java:jboss/infinispan/hibernateSearch">
<transport lock-timeout="60000"/>
<replicated-cache name="LuceneIndexesMetadata" statistics-enabled="true" mode="SYNC">
<binary-keyed-jdbc-store data-source="InfinispanCacheDS" passivation="false" purge="false" shared="true">
<binary-keyed-table>
<id-column name="ID_COLUMN" type="VARCHAR(255)"/>
<data-column name="DATUM" type="BYTEA"/>
</binary-keyed-table>
</binary-keyed-jdbc-store>
</replicated-cache>
<replicated-cache name="LuceneIndexesData" statistics-enabled="true" mode="SYNC">
<binary-keyed-jdbc-store data-source="InfinispanCacheDS" passivation="false" purge="false" shared="true">
<binary-keyed-table>
<id-column name="ID_COLUMN" type="VARCHAR(255)"/>
<data-column name="DATUM" type="BYTEA"/>
</binary-keyed-table>
</binary-keyed-jdbc-store>
</replicated-cache>
<replicated-cache name="LuceneIndexesLocking" statistics-enabled="true" mode="SYNC"/>
</cache-container>
Here is my JDBC data source from standalone-full-ha.xml:
<datasource jndi-name="java:jboss/datasources/InfinispanCacheDS" pool-name="InfinispanCacheDS" enabled="true" use-java-context="true" statistics-enabled="true">
<connection-url>jdbc:postgresql://localhost:5432/db_infinispan_cache</connection-url>
<driver>postgresql-jdbc4</driver>
<pool>
<min-pool-size>10</min-pool-size>
<max-pool-size>20</max-pool-size>
<prefill>true</prefill>
<flush-strategy>IdleConnections</flush-strategy>
</pool>
<security>
<user-name>infinispan_cache</user-name>
<password>mypassword</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker"/>
<validate-on-match>true</validate-on-match>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter"/>
</validation>
<statement>
<track-statements>true</track-statements>
</statement>
</datasource>
Here is my persistence.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="MyPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/jdbc/datasources/MyDataSourceDS</jta-data-source>
<shared-cache-mode>ALL</shared-cache-mode>
<properties>
<property name="jboss.entity.manager.factory.jndi.name"
value="java:/MyDataSourceEntityManagerFactory" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.jdbc.batch_size" value="50" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.generate_statistics" value="true" />
<property name="hibernate.connection.release_mode" value="auto" />
<!-- Transactions -->
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />
<property name="hibernate.transaction.flush_before_completion"
value="true" />
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup" />
<property name="hibernate.max_fetch_depth" value="5" />
<!-- Caching support - Infinispan -->
<property name="hibernate.cache.use_second_level_cache"
value="true" />
<property name="hibernate.cache.infinispan.cachemanager"
value="java:jboss/infinispan/container/hibernate" />
<property name="hibernate.cache.use_second_level_cache"
value="true" />
<!-- Hibernate Search properties - Generic -->
<property name="hibernate.search.reader.strategy" value="shared" />
<property name="hibernate.search.worker.execution" value="sync" />
<property name="hibernate.search.jmx_enabled" value="true" />
<!-- Hibernate Search properties - Infinispan -->
<property name="hibernate.search.infinispan.cachemanager_jndiname"
value="java:jboss/infinispan/hibernateSearch" />
<property name="hibernate.search.default.directory_provider"
value="infinispan" />
<property name="hibernate.search.infinispan.chunk_size"
value="300000000" />
</properties>
</persistence-unit>
</persistence>
When JBoss starts up, I do not see any errors. I also don't see any reference to JDBC, however. I also do not see any errors when persisting JPA objects, so it seems they are being indexed appropriately. It's just that my Hibernate Search index isn't being saved in the database as I would expect.
Can anyone shed some light on what I'm missing here?

As you noticed, the Infinispan extensions used by Hibernate Search for this purpose are not included within the Infinispan module which is part of WildFly / JBoss EAP, so you correctly downloaded the Infinispan modules from the Infinispan project.
What you are missing is that WildFly is able to isolate modules very effectively, so the first thing you have to realise is that you really don't have to match the version of Infinispan as included in WildFly.
Since you will be using the module set from infinispan.org, you should NOT configure these caches in your JBoss EAP configuration file, as the caches defined there are controlled by the clustering subsystem and will affect the cache definitions created by the Infinispan modules included in WildFly (the Infinispan modules at slot "main").
You should include an Infinispan configuration file in your Hibernate Search based application, and have it start a new CacheManager using the right module.
Alternatively you can create another application to start the CacheManager in any way you like - as long as you depend on the right Infinispan modules (avoid the "main" slot) - then register it to JNDI and have Hibernate Search look for that name.
N.B. the Hibernate Search module has a dependency to the optional Infinispan module, so it will attempt to load the right Infinispan module if it's present:
https://github.com/wildfly/wildfly/blob/84d88b8/feature-pack/src/main/resources/modules/system/layers/base/org/hibernate/search/engine/main/module.xml#L53
Be aware also that thanks to the module system, you can override / upgrade the Hibernate Search version.
In terms of versions your restrictions are :
pick an Infinispan module version compatible with your Hibernate Search version of choice
pick an Hibernate Search version compatible with the Hibernate ORM version of choice
(That's right, you can override / upgrade Hibernate ORM as well).
Assuming you are using the default version of Hibernate ORM and Hibernate Search as included in WildFly 10, you could download the Infinispan modules at version 8.2.6.Final (the latest stable release) as it also contains a module
<module name="org.infinispan.hibernate-search.directory-provider" slot="for-hibernatesearch-5.5" >
Or if you're using JBoss EAP, you might prefer to download the JBoss Data Grid distribution, which will contain the same features as the Infinispan modules.

Related

Ensure ordered shutdown of bundles in karaf

For a simple use-case, I have two bundles in Karaf as:
Bundle-Shared-Library
Bundle-My-Implementation -> depends on (1) Bundle-Shared-Library, mentioned in blueprint via depends-on attribute of the bean
Steps that I am following:
Load Bundle(1)
Load Bundle(2)
Shutdown karaf
It is evident that (2) is dependent on (1). While shutting down Karaf, Bundle(1) gets removed first, this results in the loss of in-flight messages as it cannot find its dependency and cannot process further.
I tried setting the start level of (1) both higher and lower than that of bundle(2). This did not help.
Also, I tried setting org.apache.aries.blueprint.preemptiveShutdown=false in etc/config.properties. This did not help as well.
Am I missing something here?
-- EDIT 1 --
After looking a bit over here and there, I found out that we can set a custom value for timeout in DefaultShutdownStrategy. So, as a workaround, I have done following:
<bean id="shutdownStrategy" class="org.apache.camel.impl.DefaultShutdownStrategy">
<property name="timeout" value="1" />
</bean>
I understand that this is not a clean and optimal way to do. For the time being, it somehow helps me from losing a lot of in-flight messages.
But, any suggestion or feedback would be great.
-- EDIT 2 -- Adding Blueprint File of Bundle 1
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.3.0"
xmlns:camel="http://camel.apache.org/schema/blueprint"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd
http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.3.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.3.0.xsd
">
<!-- persistent-id for shared context -->
<cm:property-placeholder persistent-id="xxx.shared" update-strategy="none" >
<cm:default-properties>
...
</cm:default-properties>
</cm:property-placeholder>
<!--jms broker connection-->
<reference id="jmsProducerConnectionFactory" interface="javax.jms.ConnectionFactory" filter="(osgi.jndi.service.name=jms/xxx.producer)" availability="mandatory" />
<bean id="xxx-producer" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsProducerConnectionFactory"/>
</bean>
<!-- Source DB Reference -->
<reference id="XDataSource" interface="javax.sql.DataSource" filter="(osgi.jndi.service.name=xxx-datasource)" availability="mandatory"/>
<!-- Datawarehouse DB Reference -->
<reference id="dw" interface="javax.sql.DataSource" filter="(osgi.jndi.service.name=xdb-datasource)" availability="mandatory"/>
<bean id="prs" class="org.apache.camel.component.sql.SqlComponent">
<property name="dataSource" ref="XDataSource"/>
</bean>
<bean id="timestamp" class="org.library.shared.TimestampImplementation" destroy-method="synchronize" depends-on="dw">
<argument index="0" ref="dw" />
<argument index="2" value="Orders" />
</bean>
<bean id="shutdownStrategy" class="org.apache.camel.impl.DefaultShutdownStrategy">
<property name="timeout" value="1" />
</bean>
<camelContext id="camel-context" xmlns="http://camel.apache.org/schema/blueprint" depends-on="timestamp">
<packageScan>
<package>org.xyz.orders.routing</package>
</packageScan>
</camelContext>
</blueprint>
The other bundle is simply a collection of few classes (a shared library), which I have included as a maven dependency. There is no blueprint file for that bundle.
Due to organizational issues, I have used dummy names at some places.

Mongo DB Authentication Failed With Spring (REST)

Still now I'm using mongodb version 2.6.9 with spring (REST). In the authentication part, I have edited the mongod.conf file and enabled
auth = true
And added the below codes in spring - applicationContext.xml file
<mongo:mongo host="localhost" port="27017" id="mongo" />
<mongo:db-factory id="mongoDbFactory"
mongo-ref="mongo"
host="localhost"
port="27017"
dbname="********"
username="******"
password="********"
/>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
<!-- Start ## Bean mapping for Restlet service -->
<bean id="basecampComponent" class="org.restlet.ext.spring.SpringComponent">
<property name="defaultTarget" ref="autoRestletAppliction" />
</bean>
<bean id="autoRestletAppliction" class="com.jiit.restlet.frontcontroller.FirstStepsApplication">
<property name="inboundRoot" ref="router" />
</bean>
<bean name="router" class="org.restlet.ext.spring.SpringBeanRouter" />
And the jar's i have used, for the above configuration,
mongo-java-driver-2.12.1.jar &
spring-data-mongodb-1.2.0.RELEASE.jar
Now, I want to upgrade my mongodb to 3.4 Version. And I have tried to edit the mongod.conf file and enabled the security,
security.authorization: enabled
And I have added admin and mydb with users and tried to connect with mongodb client like robomongo and its works fine.
The problem is i'm not able to connect with spring to mongodb.
I have updated the jars to latest version but its not working. Could you please help me ?
I had a similar kind of problem a few days back. But then I stumbled upon this http://mongodb.github.io/mongo-java-driver/2.13/getting-started/quick-tour/ and it solved all my problems of mongodb connectivity through spring.
They have provided a proper explanations and how you could connect to your mongodb with or without credentials.

Spring + RMI + transactions + weblogic

We have developed two web services (A,B) with Spring 3, Hibernate 4 & JPA.
Inside a method of service A we need to call to an method of service B. The access is through RMI.
The problem is that the two of them need to be in the same transaction. I think we followed all of the rules dealing with transactions but we cannot rollback the method in service B when service A crashes after method in service B is called.
If an exception is thrown in service A after service B is called the data that service A has changed is rolled back, but not the data changed by service B. It seems that the transaction is renewed in service B and not included in that created in service B.
We use a jndi datasource created in weblogic.
The transactional methods are annotated with:
*#Transactional( readOnly = false, isolation=Isolation.SERIALIZABLE,
rollbackFor=Exception.class, propagation = Propagation.REQUIRED )*
Here is my configuration dealing with transactions:
spring-server.xml (the only data that differs from service to service is the persistence-unit name):
*<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="SAPOY/SANOT" />
</bean>
<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="allowCustomIsolationLevels" value="true"/>
<property name="globalRollbackOnParticipationFailure" value="true" />
</bean>
<tx:annotation-driven transaction-manager="jtaTransactionManager" proxy-target-class="true" />
<!-- Servicio SAPOY.SANOT -->
<bean id="sanot" class="com.sems.sapoy.sanot.services.impl.Sanot">
<property name="sanotBiz" ref="sanotBiz" />
</bean>*
persistence.xml (the only data that differs from service to service is the persistence-unit name):
*<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="SAPOY/SANOT" transaction-type="JTA">
<description>Unidad de Persistencia del modulo SANOT</description>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/xaDS</jta-data-source>
<properties>
<!--
################################################################
HIBERNATE
################################################################
-->
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.query.factory_class"
value="org.hibernate.hql.classic.ClassicQueryTranslatorFactory" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.autoReconnect" value="true" />
<property name="hibernate.autoReconnectForPools" value="true" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WeblogicTransactionManagerLookup" />
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" />
<!--
################################################################
CONNECTION
################################################################
-->
<property name="hibernate.connection.autocommit" value="false"/>
<!--
################################################################
CACHE
################################################################
-->
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.EhCacheRegionFactory" />
<property name="hibernate.cache.use_query_cache" value="true" />
</properties>
</persistence-unit>
</persistence>*
Your DataSource/TransactionManager configurations are just fine, the only problem is that you call your other service through RMI.
The global transactions must be coordinated from the same running Thread that may enlist one or more Resources (JDBC connections/JMS queues), but it cannot span over multiple threads.
The moment you call a RMI method, that call is going to be served by a RMI server which assigns a working thread to service your RMI request. Even if that method is #Transactional the transaction will be defined at the RMI working thread boundary.
Try removing the RMI call and it will work. Implementing it over multiple servers is not a trivial thing to do. You'd probably have to use something like the Command pattern, so that the Service A can call Service B to undo when Service A fails to commit. Like I said, this is not as trivial as a global XA transaction. It requires careful design and it may lead to inconsistencies to due undos happening after other transaction already used the already committed changes.
For that you need WS-Transactions and a Application server to support it. By itself JTA manages global transactions on a Thread basis. To span transactions over multiple Threads you need a higher-level protocol like WS-Transactions.

Setting V$SESSION.program property on Glassfish JDBC Connection Pool

my Java EE App is deployed on Glassfish 3.0.1, and uses a JDBC Connection Pool to Connect to an Oracle 9i database. I am using JPA to read/write data to the database, which is working fine. However, to get better reporting regarding the load this app is putting on the database, I want to set the V$SESSION.program column for use by oracle.
From various google searches (eg. http://forums.oracle.com/forums/thread.jspa?messageID=3271623) it looks like I should just be able to add this as a property, the same as you would set any other property. So I have tried this by changing the domain.xml file for Glassfish (see below), and the V$SESSION.program property is now set on the JDBC connection pool when I view it using the Glassfish Admin Console (When I start up the glassfish server, go to the admin page and browse to Resources->JDBC->Connection Pools->MyConnectionPool->Additional Properties I can see an entry for V$SESSION.program set appropriately).
However, when I query the Oracle Database for the connections (SELECT * FROM V$SESSION), they have the same V$SESSION.program as before (which is "JDBC Thin Client"), rather than the one I set in the domain.xml and which I can see as a property of the JDBC Connection Pool on the Glassfish Admin Page.
The resources section of my domain.xml is below:
<resources>
<jdbc-connection-pool pool-resize-quantity="4" max-pool-size="16" datasource-classname="oracle.jdbc.pool.OracleDataSource" res-type="javax.sql.DataSource" steady-pool-size="4" name="mydatabasename">
<property name="datasourceName" value="OracleConnectionPoolDataSource" />
<property name="databaseName" value="mydatabasename" />
<property name="password" value="mypassword" />
<property name="portNumber" value="1521" />
<property name="serverName" value="myservername" />
<property name="url" value="jdbc:oracle:thin:#myservername:1521:mydatabasename" />
<property name="user" value="myuser" />
<property name="v$session.program" value="MyGlassfishApp" />
</jdbc-connection-pool>
<jdbc-resource pool-name="mydatabasename" jndi-name="jdbc/mydatabasename" />
</resources>
And my Persistence.xml is as below (I've deleted all the <class>...</class> lines):
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="Persistence-ejb" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/mydatabasename</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.query.timeout" value="60"/>
<property name="javax.persistence.lock.timeout" value="60"/>
<property name="javax.persistence.target-server" value="SunAS9"/>
<!-- Disable caching so we always use the DB directly -->
<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.query-results-cache" value="false"/>
</properties>
</persistence-unit>
</persistence>
EDIT:
I have tried v$session.program, V$SESSION.PROGRAM and V$SESSION.program - none have worked though... I have also tried setting the V$SESSION.program property on the EntityManager, but that didn't work (I didn't really expect it to since from what I understand the EntityManager properties are only to do with the JPA layer, not the underlying connection to the Database - but I'm trying stuff out of desperation...)
I also tried using a SessionCustomizer as suggested here. The SessionCustomizer code I used is below:
public class ProgramSessionCustomizer implements SessionCustomizer {
private static Logger logger = Logger.getLogger(ProgramSessionCustomizer.class);
#Override
public void customize(Session s) throws Exception {
logger.error("ProgramSessionCustomizer setting v$session.program");
s.getDatasourceLogin().setProperty("v$session.program", "MYprogramTEST");
logger.error("ProgramSessionCustomizer has set v$session.program");
}
}
I then set the SessionCustomizer in the persistence.xml by adding the property:
<property name="eclipselink.session.customizer" value="persistence.config.ProgramSessionCustomizer"/>
I can see the log lines, so the Customizer is definitely being called. However, I don't see the program set in the database, and I don't even see it set when I browse to the JDBC connection pool properties on the Glassfish Admin Console (which, as I said above, I do see when I set the property using the glassfish domain.xml)
Again, any more suggestions would be very welcome as I'm at a loss!
I finally found out how to set this connection property in WebSphere 8 too for a XA datasource. It can be set in the WebSphere admin console:
Resources > JDBC providers > [Oracle JDBC Driver (XA)] > Data Sources > [data source name] > Custom properties
Just add there a property with a key: connectionProperties and its value: v$session.program:PUT_YOUR_NAME_HERE
This works for me using Spring. It should works for yours Java EE app as well. The idea is to set the v$session param indirectly via properties passed to connectionProperties property
<bean class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
<property name="URL" value="${configDb.url}"/>
<property name="user" value="${configDb.user}"/>
<property name="password" value ="${configDb.password}"/>
<property name="connectionCachingEnabled" value="true"/>
<property name="connectionProperties">
<value>v$session.program:PUT_YOUR_NAME_HERE</value>
</property>
</bean>

Spring DB2 JPA Entity Manager Problem

I'm trying to configure Spring, JPA and DB2 in order to have the entity manager instance to be used in my spring controllers but according how I have configured Spring this not happens.
These are the two attempts of configuration of spring:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource" />
<bean name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="em" />
</bean>
<bean id="em"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="fileUtility" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
<property name="database" value="DB2" />
<property name="showSql" value="true" />
</bean>
</property>
</bean>
the second is this:
<!-- Entity manager factory bean. -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="Sample" />
</bean>
<!-- Entity manager bean. -->
<bean id="em" factory-bean="entityManagerFactory"
factory-method="createEntityManager" />
and the entity manager is injected in this way:
<bean id="messageService" class="utilities.services.impl.MessageServiceImpl">
<property name="entityManager" ref="em" />
</bean>
but I have always this exception:
Caused by: java.lang.IllegalArgumentException: methods with same signature createEntityManager() but incompatible return types: [interface com.ibm.websphere.persistence.WsJpaEntityManager, interface org.apache.openjpa.persistence.OpenJPAEntityManagerSPI]
I don't know how can be fixed. Has anyone encountered this problem?
Thanks in advance.
[EDIT]
This is my persistence.xml:
<?xml version="1.0"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
<persistence-unit name="fileUtility"
transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<mapping-file>META-INF/mapping.xml</mapping-file>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:db2://localhost:50000/db2admin" />
<property name="openjpa.ConnectionDriverName" value="COM.ibm.db2.jdbc.app.DB2Driver" />
<property name="openjpa.ConnectionUserName" value="db2admin" />
<property name="openjpa.ConnectionPassword" value="XXXX" />
<property name="openjpa.FlushBeforeQueries" value="true"/>
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
</properties>
</persistence-unit>
<persistence-unit name="fileUtility2" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>file_ds</jta-data-source>
<mapping-file>META-INF/mapping.xml</mapping-file>
<properties>
<property name="openjpa.Log" value="SQL=TRACE"/>
<property name="openjpa.ConnectionFactoryProperties" value="PrettyPrint=true, PrettyPrintLineLength=72"/>
</properties>
</persistence-unit>
</persistence>
WebSphere has a JPA implementation bundled. So no need to add openjpa to your lib. In fact, WebSphere is using OpenJPA, so you are not losing anything. Look here for more details
When using a jda-data-source, you need to have transaction-type="JTA". Also, you should not specify connection properties - they are specified in the datasource.
And get rid of the <provider> - the document I linked says:
If no JPA provider is configured in the element of the persistence.xml file within an EJB module, the default JPA provider that is currently configured for this server is used
I believe you're doing the wrong configuration, because you're configuring it "à la Tomcat". If you're using a Java EE application server, such as WAS, you should:
In Spring application context xml file
configure the DAO bean by a <bean> definition
configure the JNDI definition for the datasource created in the application server via a
<jee:jndi-lookup>
definition; the
name
attribute should be
persistence/XXX, where XXX shall match the
<persistence-unit name="XXX" transaction-type="JTA">
in persistence.xml file
The id attribute in the
<jee:jndi-lookup id=YYY> should point to the
name=YYY parameter of the Entity Manager definition in the DAO, this is to say,
#PersistenceContext(name=YYY) EntityManager em;
Specify
<tx:annotation-driven /> and
<tx:jta-transaction-manager />
In file
web.xml of your web app you should include a definition using the xml tag
<persistence-unit-ref> whose
<persistence-unit-ref-name> parameter shall be the
persistence/XXX JNDI name as specified in persistence.xml (shown above).
Finally, you should create a JNDI definition in the application server (AS dependant) that defines the JNDI name for the JDBC connection. This name should match the
<jta-data-source> xml tag in the persistence.xml file, and it is the only link between the JPA definition and the JDBC defined in the application server.
To round up:
Application Context Spring file
<bean class="DAO implementation class" />
<jee:jndi-lookup id="YYY" jndi-name="persistence/XXX" />
<tx:annotation-driven />
<tx:jta-transaction-manager />
persistence.xml file
<persistence-unit name="XXX" transaction-type="JTA">
<jta-data-source>jdbc/DSN</jta-data-source>
</persistence-unit>
web.xml file
...
<persistence-unit-ref>
<persistence-unit-ref-name>persistence/XXX</persistence-unit-ref-name>
</persistence-unit-ref>
...
DAO (only #PersistenceContext shown)
...
#PersistenceContext(name = "YYY")
EntityManager em;
...
Application Server: jdbc/DSN links to the connection definition, where the driver for the DBM is. Depends on both the AS and the DBM used.
Thus, you may see the connection between the DAO -> Spring Application Context file -> persistence.xml and web.xml files -> Application Server JNDI names. IF you're using a full Java EE application server (such as WAS, Weblogic or GlassFish) you don't have to use Spring interface modules; only defnitions in the app server (see Spring documentation, section 12.6.3).

Resources