Hibernate in emeddable websphere container does not find java:comp/websphere/ExtendedJTATransaction - java

I have a Java EE application which uses Hibernate 4.2.7 as persistence provider executing Junit tests in an embeddable Websphere 8.0.0 container. Database access works fine in a real (i.e. non-embedded) Websphere 8.0.0 instance. The unit tests do work when run with OpenJPA instead of Hibernate. However, running the Junit tests with Hibernate, I get the following exception:
CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "getEntity" on bean "BeanId(embeddable#classes#SomeBean, null)". Exception data: org.hibernate.service.jndi.JndiException: Unable to lookup JNDI name [java:comp/websphere/ExtendedJTATransaction]
at org.hibernate.service.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:68)
at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter$TransactionAdapter.(WebSphereExtendedJtaPlatform.java:156)
at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter$TransactionAdapter.(WebSphereExtendedJtaPlatform.java:152)
at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter.getTransaction(WebSphereExtendedJtaPlatform.java:124)
at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter.getStatus(WebSphereExtendedJtaPlatform.java:119)
at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:73)
at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:115)
at org.hibernate.service.jta.platform.internal.TransactionManagerBasedSynchronizationStrategy.canRegisterSynchronization(TransactionManagerBasedSynchronizationStrategy.java:56)
... stripped ...
It seems the implementation of WebsphereExtendedJtaPlatform is trying to get the current transaction via a JNDI lookup but fails because that JNDI name does not exist in the embedded container. Here's a snipped from org.hibernate.service.jta.platform.internal.WebsphereExtendedJtaPlatform:
public class TransactionAdapter implements Transaction {
private TransactionAdapter() {
if ( extendedJTATransaction == null ) {
extendedJTATransaction = jndiService().locate( "java:comp/websphere/ExtendedJTATransaction" );
}
}
... stripped ...
The class ExtendedJtaTransaction itself does exist on the class path inside com.ibm.ws.runtime.jar.
The settings in our persistence.xml look like this:
<persistence-unit name="BLA" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/BLA</jta-data-source>
<class>com.some.Entity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup" />
<property name="jta.UserTransaction" value="java:comp/UserTransaction" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.jdbc.fetch_size" value="100" />
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" />
</properties>
Does anyone have a solution for this?
Thanks!

Transaction strategy configuration
Hibernate requires the configuration of two essential pieces in order to properly run with transactions. The first, hibernate.transaction.factory_class, defines transactional control and the second, hibernate.transaction.manager_lookup_class, defines the mechanism for registration of transaction synchronization so the persistence manager is notified at transaction end when it needs to synchronize changes with the database. For transactional control, both container-managed and bean-managed configurations are supported. The following properties must be set in Hibernate.cfg.xml when using Hibernate with WebSphere Application Server:
for container-managed transactions:
<property name="hibernate.transaction.factory_class">
org.hibernate.transaction.CMTTransactionFactory
</property>
<property name="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
</property>
for bean-managed transactions:
<property name="hibernate.transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</property>
<property name="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
</property>
<property name="jta.UserTransaction">
java:comp/UserTransaction
</property >
The jta.UserTransaction property configures the factory class to obtain an instance of a UserTransaction object instance from the WebSphere container.
The hibernate.transaction.manager_lookup_class property is supported on the WebSphere platform by WebSphere Application Server V6.x and later, and on WebSphere Business Integration Server Foundation V5.1 and later. This property configures Hibernate to use the ExtendedJTATransaction interface, which was introduced in WebSphere Business Integration Server Foundation V5.1 and WebSphere Application Server V6.0. The WebSphere ExtendedJTATransaction interface establishes a pattern that is formalized in Java EE 5 via the JTA 1.1 specification.

Related

Getting IgniteCheckedException: Default Ignite instance has already been started exception when enabling Persistence on single Node

I am deploying an application where I need to maintain some data in Ignite cache. I used in memory Ignite cache. Here is the Ignite configuration I have used:
<property name="cacheConfiguration">
<list>
<bean
class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="IGNITE_DATA" />
<property name="cacheMode" value="PARTITIONED" />
<property name="atomicityMode" value="ATOMIC" />
<property name="writeSync"
value="PRIMARY_SYNC" />
<property name="backups"
value="${IGNITE_CACHE_BACKUPS}" />
</bean>
</list>
</property>
Now when I deployed multiple instances of my application and stored data in Ignite cache. Its shared among all the application instances.
Even if any any instance goes down and comes up after sometime it has the latest data via Ignite cache sync.
But issue occurs when all the application instances go down. When they come up data is gone since it was not persisted. For persistence I used dataStorageConfiguration property and enabled the persistence. Here is the change I added to Ignite configuration:
<property name="dataStorageConfiguration">
<bean
class="org.apache.ignite.configuration.DataStorageConfiguration">
<!-- Enabling Apache Ignite Persistent Store. -->
<property name="defaultDataRegionConfiguration">
<bean
class="org.apache.ignite.configuration.DataRegionConfiguration">
<property name="persistenceEnabled" value="true" />
</bean>
</property>
<!-- Changing Write Ahead Log Mode. -->
<property name="storagePath" value="${IGNITE_BC_STORE_PATH}"/>
<property name="walMode" value="LOG_ONLY" />
</bean>
</property>
Now when I deploy my application and I try and start Ignite from Java code as mentioned below:
log.info("Initializing IGNITE...");
ignite = Ignition.start(getClass().getResource(CONF_FILE));
I get an exception every time stating the default instance has already started.Tried several things but didn't work. Even if I remove the CacheConfiguration from Ignite Configuration and just keep dataStorageConfiguration I still getting the same error. Error is :
Caused by: class org.apache.ignite.IgniteCheckedException: Default Ignite instance has already been started.
at org.apache.ignite.internal.IgnitionEx.start0(IgnitionEx.java:1141)
at org.apache.ignite.internal.IgnitionEx.startConfigurations(IgnitionEx.java:1076)
at org.apache.ignite.internal.IgnitionEx.start(IgnitionEx.java:962)
at org.apache.ignite.internal.IgnitionEx.start(IgnitionEx.java:881)
at org.apache.ignite.Ignition.start(Ignition.java:373)
Normally this error comes when we try and run multiple Ignite nodes under same JVM but here I am running single node per JVM. Then also getting the error.
Please do correct me if I am wrong.
Any help here will be appreciated.
Most probably, you have more than one IgniteConfiguration bean in your config file. If one configuration bean extends another one, then make sure, that the parent is abstract.
I have resolved the issue. Seems like the issue was not woth the Ignite configuration but was with Spring Framework configuration.
I was creating the bean for the Ignite class using the lazy-init=true. I switched that to the eager-init and that resolved my issue.
Not sure how exactly it solved this but it worked at least in my case.

Retrieve information from existing database using JPA

I'm developing a Java Web Project using JPA (EclipseLink) to connect with our databases. I have a persistence unit where I configured the database where my data is going to persisted. The question is that I also have to access another database that is already created and populated with info, and I just want to access one table of this database to retrieve some information. How can I access it using JPA just to retrieve info (neither save nor update anything).
After setting up your entity managers you can just run a native query :
entityManager.createNativeQuery("SELECT ...");
So, you can create another persistent-unit poiting to your other database
<persistence-unit name="read-and-write-database">
...
<properties>
<!-- conection -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/database-write" />
<.../>
</properties>
</persistence-unit>
<persistence-unit name="read-database">
...
<properties>
<!-- conection -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/database-read" />
<.../>
</properties>
</persistence-unit>
And, in a SE environment, you would something like that to create the EntityManager:
EntityManagerFactory readWriteEntityManagerFactory = Persistence.createEntityManagerFactory("read-and-write-database");
EntityManager readWriteEntityManager = readWriteEntityManagerFactory.createEntityManager();
EntityManagerFactory readEntityManagerFactory = Persistence.createEntityManagerFactory("read-database");
EntityManager readEntityManager = readEntityManagerFactory.createEntityManager();
if you are in a container, the PersistenceContext anotation have the unitName field that you can use to define the persistente-unit
Keep in mind that by doing that, you will have two different persistence context. So, changes made in one of then, not gonna be "visiable" to the other one until the persistence of the data.
obs: sorry any typo.
I hope this helps you.
Cheers

how does spring know which connection pool to use?

How does spring know which connection pool to use?
As is known ,you tell the spring framework a persistence-unit name,and annotate the entity manager with #PersistenceContext,and with Persistence.xml configured.Spring does every thing for you.
I am very confused about the spring annotation "#PersitenceContext" above the entityManager field.
My persistence.xml is as below :
<persistence-unit name="hibernate.recommendation_report.jpa">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:#192.168.113.226:11521:BOSS" />
<property name="javax.persistence.jdbc.user" value="xxxx" />
<property name="javax.persistence.jdbc.password" value="xxxx" />
</properties>
</persistence-unit>
My tomcat server and my webapp work well when and after for a short peoriod of time after the starting up of tomcat server.But hours later,the server reports a sqlexception "Connection already closed".
Is this the problem of misusing db connection pool? How do the spring framework choose a c3p0 or DBCP ? How would I specify the connection pool? Or is the tomcat uses the default DBCP as the connection pool?
U can make your tomcat server or other app server provide the JNDI datasource. So that, the your server container's self-contained connection pool can take good care of your the database connection/session.
Tomcat in your case, you specify the JNDI datasource in the $TOMCAT_HOME/conf/context.xml or server.xml:
<Resource name="jdbc/sample" auth="Container"
type="com.mchange.v2.c3p0.ComboPooledDataSource"
username=...
password=...
url=...
driverClassName=...
/>
the type attribute tells the tomcat which connection pool to use.
By default tomcat6 uses DBCP with type of "java.sql.DataSource".
Make sure to use the JNDI reference in your persistence.xml:
<persistence version="2.1" ....>
<persistence-unit name="hibernate.recommendation_report.jpa">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<non-jta-data-source>java:comp/env/jdbc/sample</non-jta-data-source>
</persistence-unit>
</persistence>
Or use spring xml to config the datasource bean to inject into the your entityManagerFactory.Please refer to here.
<jee:jndi-lookup id="dataSource" jndi-name="java:sample"/>
See other JNDI resource attributes available for DBCP.
Note: the "java:comp/env/" prefix in persistence.xml data-source is very import.Without it, Spring will not look for the pool provided by your application server to fetch datasource but just use the attribute to construct a simple datasource.
Note: tomcat8 itself provides a even better pool.If you upgrade to tomcat8.

Access Datasource through the JPA project

I have created the JPA project (I use OpenJPA 2.0 as the JPA provider).
IDE: IBM Rational Softwara architect for Websphere Software(RAD)
JPA Provider: OpenJPA
Version: 2.0
Database: Oracle
I created the datasource in Websphere(Version 7.0) and tried to accss the datasource through the JNDI. Please find the persistence.xml bellow.
<persistence version="2.0">
<persistence-unit name="DataSourceDemo">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>oracleDS</jta-data-source>
<class>com.nyl.ltc.auditlog.model.NylBatchPrint</class>
<properties>
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
<property name="openjpa.ConnectionUserName"
value="admin" />
<property name="openjpa.ConnectionPassword" value="admin" />
<property name="openjpa.jdbc.Schema" value="SMSVC" />
</properties>
</persistence-unit>
</persistence>
All the Database transaction was success but I am getting the bellow exception.
Exception in thread "Attachment 49459" java.lang.UnsupportedOperationException: cannot get the capability, performing dispose of the retransforming environment
at com.ibm.tools.attach.javaSE.Attachment.loadAgentLibraryImpl(Native Method)
at com.ibm.tools.attach.javaSE.Attachment.loadAgentLibrary(Attachment.java:253)
at com.ibm.tools.attach.javaSE.Attachment.parseLoadAgent(Attachment.java:235)
at com.ibm.tools.attach.javaSE.Attachment.doCommand(Attachment.java:154)
at com.ibm.tools.attach.javaSE.Attachment.run(Attachment.java:116)
Exception in thread "P=221586:O=0:CT" java.lang.UnsupportedOperationException: cannot get the capability, performing dispose of the retransforming environment
at sun.instrument.InstrumentationImpl.isRetransformClassesSupported0(Native Method)
at sun.instrument.InstrumentationImpl.isRetransformClassesSupported(InstrumentationImpl.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.apache.openjpa.enhance.ClassRedefiner.canRedefineClasses(ClassRedefiner.java:123)
at org.apache.openjpa.enhance.ManagedClassSubclasser.prepareUnenhancedClasses(ManagedClassSubclasser.java:122)
at org.apache.openjpa.kernel.AbstractBrokerFactory.loadPersistentTypes(AbstractBrokerFactory.java:304)
at org.apache.openjpa.kernel.AbstractBrokerFactory.initializeBroker(AbstractBrokerFactory.java:228)
at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:202)
at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:213)
at com.ibm.ws.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:45)
at com.ibm.ws.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:30)
at com.nyl.ltc.auditlog.util.JPAUtil.getEntityManager(JPAUtil.java:45)
at com.nyl.ltc.auditlog.dao.sericeImpl.AuditLogDAOServiceImpl.persist(AuditLogDAOServiceImpl.java:27)
at com.nyl.ltc.auditlog.serviceImpl.AuditLogServiceImpl.persistAuditLog(AuditLogServiceImpl.java:20)
at com.nyl.ltc.auditlog.handlerImpl.AuditLogHandlerImpl.persistAuditlog(AuditLogHandlerImpl.java:22)
at com.main.Main.main(Main.java:19)
2203 DataSourceDemo INFO [P=221586:O=0:CT] openjpa.Enhance - Creating subclass for "[class com.nyl.
Please let me know why I got tis exception and how can I resolve it?
The Apache OpenJPA (JPA 1.0) engine is shipped with Websphere 7 (Java EE 5). The classloader by default load the internal OpenJPA implementation. May you need to change the classloader policy.
See more in WebSphere Application Server V7: Understanding Class Loaders.

Spring Bootstrap Context for dropping Tables should they exist

I am trying to create an application bootstrap that will drop all the tables in the application if they exist and then intialise them with fresh data.
I have created a Spring Context that loads the datasource context - however I dont know how to override the initialisation of the datasource such that the behaviour can be customised depending on how the datasource is loaded. So.. using Hibernate as my JPA implementation..
If the datasource is loaded from the application - then I would like the schemas to update:
<persistence-unit name="myDB" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
If the datasource is loaded from the bootstrap - then I need to overload this behaviour somehow so that the database is always created from scratch before fresh data is loaded:
<persistence-unit name="myDB" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
The approach I have been taking doesn't work as I would load the datasource using the 'update' setting and then drop the tables if they exist before attempting to load new data. However - the tables no longer exist for writing data !
Thanks in advance
Simon
You can pass JPA properties from Spring configuration instead of persistance.xml and use placeholder that can be configured by PlaceholderConfigurer (possibly system-properties="OVERRIDE"), or Spring profiles (since 3.1) or using Maven filtering:
<util:map id="jpaPropertyMap" key-type="java.lang.String" value-type="java.lang.Object">
<entry key="hibernate.hbm2ddl.auto" value="${database.ddl.mode}" />
</util:map>
<bean id="managementEntityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource"
p:jpaPropertyMap-ref="jpaPropertyMap" />

Categories

Resources