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"
开发者_StackOverflow中文版 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>
definitionconfigure the JNDI definition for the datasource created in the application server via a
<jee:jndi-lookup>
definition; thename
attribute should bepersistence/XXX
, where XXX shall match the<persistence-unit name="XXX" transaction-type="JTA">
in persistence.xml fileThe id attribute in the
<jee:jndi-lookup id=YYY>
should point to thename=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 thepersistence/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).
精彩评论