I am using OpenJPA in cxf(jax-rs) + Struts 2. No external transaction manager. Why am I getting "Can only perform operation while a transaction is active."?
My persistence.xml is like this:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="myPU"
transaction-type="RESOURCE_LOCAL">
<class>com.bb.bba.entity.Advertisement</class>
<class>com.bb.bba.entity.Poi</class>
<properties>
<property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.ClientDriver" />
<property name="openjpa.ConnectionURL" value="jdbc:derby://localhost:1527/bba;create=true" />
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema" />
<property name="openjpa.DynamicEnhancementAgent" value="false" />
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
<property name="openjpa.ConnectionUserName" value="APP" />
<property name="openjpa.ConnectionPassword" value="asdasd" />
<property name="openjpa.Log" value="SQL=TRACE"/>
</properties>
</persistence-unit>
</persistence>
I am getting the following error.
35692 2012-06-02 03:50:57,847 DEBUG [http-33791-1] resolver.DefaultTraversableResolver.initJpa (DefaultTraversableResolver.java:77) - Found javax.persistence.PersistenceUtil on classpath.
35729 2012-06-02 03:50:57,884 DEBUG [http-33791-1] resolver.DefaultTraversableResolver.initJpa (DefaultTraversableResolver.java:91) - Instantiated an instance of org.apache.bval.jsr303.resolver.JPATraversableResolver.
35755 2012-06-02 03:50:57,910 TRACE [http-33791-1] jsr303.DefaultMessageInterpolator.loadBundle (DefaultMessageInterpolator.java:189) - ValidationMessages not found by thread local classloader
35755 2012-06-02 03:50:57,910 TRACE [http-33791-1] jsr303.DefaultMessageInterpolator.loadBundle (DefaultMessageInterpolator.java:189) - ValidationMessages not found by validator classloader
35756 2012-06-02 03:50:57,911 DEBUG [http-33791-1] jsr303.DefaultMessageInterpolator.getFileBasedResourceBundle (DefaultMessageInterpolator.java:176) - ValidationMessages not found. Delegating to org.apache.bval.jsr303.ValidationMessages
35778 2012-06-02 03:50:57,933 DEBUG [http-33791-1] xml.ValidationParser.parseXmlConfig (ValidationParser.java:88) - No META-INF/validation.xml found. Using annotation based configuration only.
646 myPU INFO [http-33791-1] openjpa.Runtime - OpenJPA dynamically loaded a validation provider.
922 myPU INFO [http-33791-1] openjpa.Runtime - Starting OpenJPA 2.1.1
1703 myPU INFO [http-33791-1] openjpa.jdbc.JDBC - Using dictionary class "org.apache.openjpa.jdbc.sql.DerbyDictionary".
11326 myPU WARN [http-33791-1] openjpa.Enhance - Creating subclass for "[class com.bb.bba.entity.Poi, class com.bb.bba.entity.Advertisement]". This means that your application will be less efficient and will consume more memory than it would if you ran the OpenJPA enhancer. Additionally, lazy loading will not be available for one-to-one and many-to-one persistent attributes in types using field access; they will be loaded eagerly instead.
Here I am
...... nonfatal user error>
org.apache.openjpa.persistence.TransactionRequiredException: Can only
perform operation while a transaction is active.
at org.apache.openjpa.kernel.BrokerImpl.assertActiveTransaction(BrokerImpl.java:4658)
at org.apache.openjpa.kernel.DelegatingBroker.assertActiveTransaction(DelegatingBroker.java:1386)
at org.apache.openjpa.persistence.EntityManagerImpl.flush(EntityManagerImpl.java:661)
at com.bb.bba.dao.MyDao.createPoi(MyDao.java:21)
at com.bb.bba.services.Service.createPoi(POIService.java:36)
You will have to open a transaction before you can perform operations on the EntityManager. That's expected behavior. You will have find some transaction strategy for your application. So you have to decide which component opens transactions (especially on which layer) and how it is done (declarative or programmatic).
What other frameworks are you using? If you are for example also using Spring, you can very easily manage transactions using Spring's declarative transaction management support.
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/transaction.html
The problem is solved. I was using resource_local which means I am responsible for the transaction. Adding em.getTransaction.begin solved the issue.
Related
We are facing issue in our application with respect to the persistence configuration. The application runs on TomEE Plus (7.0) and uses Open JPA implementation. Below is the error which we are getting
<openjpa-2.4.2-r422266:1777108 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: There were errors initializing your configuration: <openjpa-2.4.2-r422266:1777108 fatal user error> org.apache.openjpa.util.UserException: A connection could not be obtained for driver class "oracle.jdbc.xa.client.OracleXADataSource" and URL "jdbc:oracle:thin:#//mydburl.abc.com:1881/MYSID.ABC.COM". You may have specified an invalid URL.
We dont' get the above error when using oracle.jdbc.driver.OracleDriver. The XA driver settings were working fine on IBM WebSphere 8.5. Is there anything else which we need to configure in TomEE+ to get it working?
Update
Adding the persistence.xml file as well
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
version="1.0">
<persistence-unit name="MySchema" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>myjndi</jta-data-source>
<class>com.abc.jpa.entity.Tuser</class>
<class>com.abc.jpa.entity.Taddress</class>
<properties>
<property name="tomee.jpa.factory.lazy" value="true"></property>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.xa.client.OracleXADataSource" />
<property name="javax.persistence.jdbc.url"
value="jdbc:oracle:thin:#//mydburl.abc.com:1881/MYSID.ABC.COM" />
<property name="javax.persistence.jdbc.user" value="userName" />
<property name="javax.persistence.jdbc.password" value="password" />
</properties>
</persistence-unit>
</persistence>
As mentioned, it works fine if I use oracle.jdbc.driver.OracleDriver as the jdbc driver class
I am using EclipseLink as a JPA Implementation. While deploying in Wildfly-10.1.0.Final, I always get the error No Persistence provider for EntityManager named <the persistence unit name>. I have followed the step in the links:
https://docs.jboss.org/author/display/WFLY10/JPA+Reference+Guide#JPAReferenceGuide-UsingEclipseLink
https://developer.jboss.org/thread/273134
The steps and the module.xml exactly matches mine.In standalone.xml I have enabled the system property as stated in the first link mentioned above
I enabled the trace logging and found that the below :
[org.hibernate.jpa.HibernatePersistenceProvider] (default task-4) Excluding from consideration due to name mis-match
Persistence Provider :org.eclipse.persistence.jpa.PersistenceProvider
JDK Version :1.8
Request if someone can shed some light where I am going wrong.
Added the trace as
Caused by: javax.persistence.PersistenceException: No Persistence provider for EntityManager named AAAAA_BBBB
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
Other trace of Mismatch
2017-02-23 17:47:09,276 DEBUG [org.hibernate.jpa.HibernatePersistenceProvider] (default task-55) Checking persistence-unit [name=AAAAA_BBBB, explicit-provider=org.eclipse.persistence.jpa.PersistenceProvider] against incoming persistence unit name [AAAAA_BBBB]
2017-02-23 17:47:09,276 DEBUG [org.hibernate.jpa.HibernatePersistenceProvider] (default task-56) Checking persistence-unit [name=AAAAA_BBBB, explicit-provider=org.eclipse.persistence.jpa.PersistenceProvider] against incoming persistence unit name [AAAAA_BBBB]
2017-02-23 17:47:09,277 DEBUG [org.hibernate.jpa.HibernatePersistenceProvider] (default task-56) Excluding from consideration due to name mis-match
Additional Traces
2017-02-24 05:32:49,031 TRACE [org.hibernate.jpa.boot.spi.ProviderChecker] (default task-7) Checking requested PersistenceProvider name [org.eclipse.persistence.jpa.PersistenceProvider] against Hibernate provider names
2017-02-24 05:32:49,031 DEBUG [org.hibernate.jpa.HibernatePersistenceProvider] (default task-11) Excluding from consideration due to provider mis-match
2017-02-24 05:32:49,031 TRACE [org.hibernate.jpa.boot.spi.ProviderChecker] (default task-7) Found no match against Hibernate provider names
The persistence.xml
<persistence-unit name="AAA_BBB" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:/<jndi-Name in standalone</jta-data-source>
<class>...</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="<url>"/>
<property name="javax.persistence.jdbc.user" value="<username>"/>
<property name="javax.persistence.jdbc.password" value="<pwd>"/>
</properties>
</persistence-unit>
<persistence-unit name="CCC_DDD" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:/<jndi-Name in standalone</jta-data-source>
<class>...</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="<url>"/>
<property name="javax.persistence.jdbc.user" value="<username>"/>
<property name="javax.persistence.jdbc.password" value="<pwd>"/>
</properties>
</persistence-unit>
Was finally able to resolve the issue in a little weird way (probably)
Step 1 : created a module directory under the name (com.abc.persistence:main)
Step 2 copied all the related jars of eclipselink and jipijapa into the same module and referred it.
Step 2. Removed the system property "eclipselink.archive.factory"
It works clean.
What I analysed was if one of the system property is put then others like the target server are never added to the properties map (I checked somewhere in the code). Once I removed I think all the others also gets added and hence it works, because I will be little surprised if creating the above directory in the module (Step 1 above ) made it work.
I am deploying a simple web application to WildFly 10 from NetBeans to try and teach myself Java EE. However, I get the following error when trying to run a jpql query from NetBeans:
javax.persistence.PersistenceException: No Persistence provider for EntityManager named WebApplication1PU
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:85)
This is despite the fact that I have defined a persistence provider. This is my persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" 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">
<persistence-unit name="WebApplication1PU" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:/jboss/db</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2012Dialect"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
When I test my datasource in WildFly it works:
My JPA Subsystem's default datasource is configured as java:/jboss/db
I have it listed as a persistence unit in WildFly:
I am using JTDS driver for MS SQL Server and I do get this error on startup of the server that I can't get rid of:
10:33:07,600 ERROR [org.jboss.as.controller.management-operation] (ServerService Thread Pool -- 33) WFLYCTL0013: Operation ("add") failed - address: ([
("subsystem" => "datasources"),
("jdbc-driver" => "JTDS")
]) - failure description: "WFLYJCA0041: Failed to load module for driver [net.sourceforge.jtds]"
However, as I said, testing the datasource works, so this shouldn't matter. Can anyone help me?
As a comment mentioned, it's saying Wildfly cannot find the provider module.
Download: https://sourceforge.net/projects/jtds/files/jtds/1.3.1/jtds-1.3.1-dist.zip/download - which is the jtds JDBC driver,
and install it into the /modules directory of wildfly.
You can launch the ./jboss-cli.sh to install modules.
See: JTDS module under WildFly (JBoss)
Give a bit more insight into it.
This URL: http://www.mastertheboss.com/jboss-server/jboss-datasource/configuring-a-datasource-with-postgresql-and-jboss-wildfly
Has how to install postgres jdbc drivers into wildfly, but it's effectively the same process for other JDBC drivers, just package name change etc.
In persistence-unit properties you are missing the following
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.username" value="dbroot"/>
<property name="hibernate.connection.password" value="password"/>
I have a dynamic web project that creates and writes Derby database. Everything works fine. Here is the persistence.xml I used:
<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"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="alerts" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>test.Alert</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby:databases/bDb;create=true" />
<property name="javax.persistence.jdbc.user" value="user" />
<property name="javax.persistence.jdbc.password" value="user-pwd" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode"
value="database" />
<property name="eclipselink.logging.level" value="FINEST" />
<property name="eclipselink.logging.level.sql" value="FINEST" />
</properties>
</persistence-unit>
Now I would like to create a java project that reads the same database. So I use the same persistence.xml (except that I change "create=true" to "create=false" since I don't want to create a new table). but I got this error:
[EL Severe]: ejb: 2014-12-28 22:27:20.379--ServerSession(1488953836)--Thread(Thread[DefaultQuartzScheduler_Worker-7,5,main])--Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Database 'databases/bDb' not found.
Error Code: 40000
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:326)
at org.eclipse.persistence.sessions.DefaultConnector.connect(DefaultConnector.java:138)
at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:162)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.setOrDetectDatasource(DatabaseSessionImpl.java:204)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:741)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:239)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:685)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:204)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:304)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:336)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:302)
If I use "create=true", it will create a new database instance (it is different from the one I created from the web project). How do I fix this problem? Thanks a lot!
Since you're using a relative filename in your jdbc.url (databases/bDb), Derby is looking for the database relative to your application start directory.
And your two separate applications have two separate directories in which they are being run.
You could address this in a number of ways:
Arrange for each application to be run from the same directory
Use an absolute database path name, not a relative one, in your jdb.url value
Use the Derby Network Server configuration, not the Derby Embedded configuration
And there are undoubtedly other approaches.
I have a core library that has an interface that I want to expose as an OSGI service in Fuse ESB (Apache ServiceMix and Karaf). The goal is to allow other bundles to use it. The service uses JPA (OpenJPA) and Spring. The following is the interface:
public interface PatientService {
public Patient find(Integer id);
}
and the class:
#Repository
public class PatientServiceJpaImpl implements PatientService {
#PersistenceContext(unitName="psu")
private EntityManager entityManager;
#Override
public Patient find(Integer id) {
return entityManager.find(Patient.class, id);
}
}
The following is an abbreviated META-INF/spring/beans.xml:
<beans xmlns="http://www.springframework.org/schema/beans" ...>
<context:annotation-config />
<context:component-scan base-package="..." />
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="psu" />
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>
And the META-INF/persistence.xml (also abbreviated):
<persistence xmlns="http://java.sun.com/xml/ns/persistence" ...>
<persistence-unit name="psu" transaction-type="RESOURCE_LOCAL">
<class>...</class>
</persistence>
In a non-OSGi environment, everything works great. It uses the felix maven-bundle-plugin, so to create the OSGi service, I added the following OSGI-INF/blueprint/osgi-context.xml:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<bean id="patientService" class="com.test.service.PatientServiceJpaImpl" />
<service id="osgiPatientService" ref="patientService" interface="com.test.service.PatientService" />
</blueprint>
The bundle is deployed successfully and the service is registered. The problem is that when the PatientService is referenced from another bundle, the entity manager has not been injected, thus throwing a NullPointerException in the find(Integer id) method. The following is a snippet of the consumer's META-INF/spring/consumer-context.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/osgi
http://www.springframework.org/schema/osgi/spring-osgi.xsd">
<bean id="patientServiceImpl" class="com.test.ws.PatientWebServiceImpl" >
<property name="patientService">
<osgi:reference interface="com.test.service.PatientService"/>
</property>
</bean>
...
</beans>
Just to be clear, the PatientService is injected in the consumer bundle, but the entity manager is not injected in the provider bundle. Also, it does not appear to be an issue with the persistence unit due to the following log output when starting the original service:
125 psu TRACE [SpringOsgiExtenderThread-14] openjpa.Runtime - org.apache.openjpa.persistence.PersistenceProviderImpl#24a5031d creating container org.apache.openjpa.persistence.EntityManagerFactoryImpl#4d6f77b6 for PU psu.
To get an idea what is going on, I logged the the object memory reference and stack trace in the constructor of the PatientServiceJpaImpl class. The constructor was called twice (creating two different objects):
The first output appears to originate from the osgi container starting from org.apache.felix and more or less ending in org.apache.aries.blueprint.
The second output appears to originate from the spring framework starting from org.springframework.osgi and more or less ending in org.springframework.beans.BeanUtils.
When the consumer service is called, the reference it has is to the blueprint instantiated object, which does not have an injected entity manager. Also from the logs, the persistence unit is instantiated after the blueprint instantiation of the PatientServiceJpaImpl object.
I have searched and tinkered with this issue for quite a while and I've run out of ideas. The irony is that it actually worked at one point, but I had made so many changes to get it to work that it was a rats nest that I was not able to back out of successfully.
Why is the persistence context not injected in the blueprint managed object? Any ideas will be appreciated. Thanks.
I'm not sure if this is going to work, cause you are mixing spring with blueprint. I have a working application based only on blueprint and I'm quite happy. For your use-case I'd suggest using blueprint at least for your JPA part. You still can use spring-dm for using the jpa classes as services.
<blueprint default-activation="eager"
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0" xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0">
<bean id="patientService" class="com.test.service.PatientServiceJpaImpl" >
<jpa:context property="em" unitname="dn1" />
<tx:transaction method="*" value="Required" />
</bean>
<service id="osgiPatientService" ref="patientService" interface="com.test.service.PatientService" />
</blueprint>
Your PatientServiceJPAImpl I would change to not contain any annotations.
public class PatientServiceJpaImpl implements PatientService {
protected EntityManager em;
#Override
public Patient find(Integer id) {
return em.find(Patient.class, id);
}
}
A good way to deal with this would be to use Gemini JPA. With Gemini JPA, your JPA bundle would automatically expose an EntityManagerFactory OSGi service, based on the configurations in your persistence.xml. Thus, in the JPA client bundle, the blueprint just needs to import this service with a filter condition specifying the persistence unit name.
Here's a small implementation on those lines: mvc-osgi
If the EMF service doesn't work for you, you can use the EntityManagerFactoryBuilder service exposed by the Gemini JPA bundle to manually create the EMF. This would require calling the "createEntityManagerFactory".