How to get EntityManager(s) for mulitple persistence units - java

I am writing a JEE7 application that runs in WebSphere Liberty Profile 8.5.5. We are using JPA (which is implemented via Eclipselink in WLP).
I have multiple persistence units in the same 'persistence.xml' file. I also need to access two of those units in the same class.
I am getting a runtime error when I try to use the second EntityManager:
#PersistenceContext(unitName = "wwer-list")
private EntityManager entityManagerWwerList;
#PersistenceContext(unitName = "main-dashboard")
private EntityManager entityManagerMainDashboard;
E WTRN0062E: An illegal attempt to use multiple resources that have only one-phase capability has occurred within a global transaction.
How do I get rid of this error?
Also, all of the tables I am using are only needed for reading. So how can I specify that I only want read-only access to JPA?

This issue is prompting because one of your datasource configured as (single phase commit) using ConnectionPoolDataSource and other is configured with XADataSource.
If you want to continue with the same datasource configuration, you will have to update your Server configuration to "Acccept Heuristic Hazard".
In the admin console, click the EAR, select the check box "Accept heuristic hazard". Re-start the server.
This link to enable the Last Participant Support may also help.
http://www.ibm.com/support/knowledgecenter/SSAW57_7.0.0/com.ibm.websphere.nd.doc/info/ae/webui_pme/ui/ueac_laoextensionsettings.html

I can't tell for sure without your persistence.xml and server.xml configurations, but it looks like the <dataSource> elements backing your <persistence-unit> configurations are not XA capable.
By default, a <dataSource> should be a javax.sql.XADataSource (and therefore XA capable), however if you are using a JDBC driver that does not provide an XADataSource implementation, Liberty will pick a simpler DataSource implementation (i.e. javax.sql.ConnectionPoolDataSource or plain javax.sql.DataSource).
A global transaction is whenever you issue a UserTransaction.begin() and lasts until you issue a commit() or a rollback(). There are other ways that you can get into a global transaction too.
Since you want read-only access, converting your DataSources to XA would probably be overkill. Instead, try to eliminate the global transactions from the equation. If you can't eliminate the global transactions, you can specify XADataSource in your server.xml in the following way:
<dataSource type="javax.sql.XADataSource" ...>
<jdbcDriver .../>
<properties .../>
</dataSource>

Related

Using an EJB outside container

I am currently creating a J2EE application and there is a part of it that is running outside the container, using a ServletContextListener to launch it.
However I also need to access the database from this part.
I currently have an Entity and a Stateless Session bean to fetch use the EntityManager.
I tested multiple things ( EntityManagerFactory, Initial Context, EJBContainer ) but I didn't manage to make any of them work.
How do I need to do it ?
You do not need EJB, actually you cannot create Ejbs outside the container. You need JPA, an OR-mapper and JDBC.
These normally are correctly configured in your EJB-Container. Outside the container you have to do that yourself.
You have to define your dependencies right, so that the correct JDBC-Driver is available and the OR-Mapper (probably eclipselink or hibernate?)
After that, you need define a presistence.xml to define the Entities to be used and to define how the DBMS is accessed via JDBC.
If that all is correctly configured EntityManagerFactory is the correct way to create an EntityManger for the persistence-unit defined in persistence.xml.
There are many examples available on the net. e.g.:
https://examples.javacodegeeks.com/enterprise-java/jpa/java-persistence-xml-example/
should work, if you are using eclipselink.
https://docs.jboss.org/hibernate/orm/3.6/quickstart/en-US/html/hibernate-gsg-tutorial-jpa.html
in case of Hibernate.

websphere wasjdbcDataSource to XADataSource

i already setup oracle xadatasource in websphere, and i want get datasource by using spring context lookup jndi , exception happen when i start my app : WasjdbcDataSource incompatible with javax.sql.XADataSource.
how can i solve this?
In a Java EE application server, such as WebSphere Application Server, even though you configure the XA-capable javax.sql.XADataSource, the application (and Spring) should always expect to use it as javax.sql.DataSource. Look in the Spring configuration if there is a way to indicate the expected type of javax.sql.DataSource rather than javax.sql.XADataSource. The XADataSource API is intended only for the application server's own internal use in order to accomplish two-phase commit. The user always interacts with it as javax.sql.DataSource, and gains the ability to enlist multiple resources in a single global transaction.

Share Hibernate connection with other libraries

I'm writing a web application in Java and use Hibernate to map the database with my java objects. In Hibernate I connect to the database using C3PO pool. Now I need to schedule some tasks. Herefore I will use Quartz. Now the scheduled tasks will be stored in the database. It is possible to share the connection pool of C3PO with Quartz? So that the database settings are in one and the same file and that only one library is responsible to open a databaseconnection.
This is sort of a subjective thing, but suffice it to say, if you want to share the connection you have a number of options.
If you are using spring, define the c3p0 connection pool as a bean and inject it into both the Hibernate session factory and the Quartz scheduler beans.
If you are trying to stay "pure" and not using Spring, you can define your a JNDI based data-source at the container level.
There are some nuances with both approaches.
Unfortunately without indicating how "portable" you are trying to be and what you are currently using beyond just 'java', 'quartz-scheduler' and 'c3p0' as tags an answer will be vague at best.
EDIT
Thanks to the OP for adding additional information.
So with regard to that information, if you are using a Dynamic Web Project, you may be able to add a container specific deployment descriptor to WebContent directory.
For tomcat, META-INF/context.xml
For Jetty, WEB-INF/jetty-web.xml
With those, you can define a JNDI data source. Refer to the specific container for information on how to do that. Once done, Hibernate and Quartz can be configured to use a JNDI reference for the data source you have configured.

single Transaction across Hibernate session and plain jdbc

Is it possible to use a single Transaction boundary for Hibernate Session and a plain JDBC query. ?
The database and the datasource configurations are similar for both.
Yes. Use HibernateTransactionManager. Below is taken from its javadoc
This implementation is appropriate for applications that solely use
Hibernate for transactional data access, but it also supports direct
data source access within a transaction (i.e. plain JDBC code working
with the same DataSource). This allows for mixing services that access
Hibernate (including transactional caching) and services that use
plain JDBC (without being aware of Hibernate)! Application code needs
to stick to the same simple Connection lookup pattern as with
DataSourceTransactionManager (i.e. DataSourceUtils.getConnection or
going through a TransactionAwareDataSourceProxy).
Note that to be able to register a DataSource's Connection for plain
JDBC code, this instance needs to be aware of the DataSource (see
setDataSource). The given DataSource should obviously match the one
used by the given SessionFactory. To achieve this, configure both to
the same JNDI DataSource, or preferably create the SessionFactory with
LocalSessionFactoryBean and a local DataSource (which will be
autodetected by this transaction manager).

Custom resource in JNDI on different application servers

Preface:
Most of J2EE applications are using container managed datasources through JNDI. This is fine as it gives one place for configuring these connections.
The problem arises when we want to use ORM framework (like hibernate) or something that have to know the default schema (mostly for Oracle, may be others too), which can be different from the username that is used to connect to the DB.
I want to put the default schema name somewhere close to the datasource definition. One of the options would be to put it in JNDI. I will then manually read of from there before construction the EntityManager (well actually using Spring).
As I found out there is a simple way to specify custom resource (in this situation it will be String with default schema name) in Apache Tomcat like this (correct me if I'm wrong):
<Environment name="schemaNames/EmployeeDB"
type="java.lang.String"
value="empl"
description="Schema name of Employees Database for HR Applications"/>
Anyway, considering this can be done in Apache Tomcat, how should I configure the same custom JNDI resource (of String type) within other application servers:
JBoss 4/5
WebSphere 6/7
WebLogic 9/10
If you know about other servers that would be great too.
Also, as an alternative I don't want to put the schema name in system properties or environment variables.
Thank you very much !
Update:
Found some way of achieving it on JBoss. I didn't test it tho.
http://forums.java.net/jive/thread.jspa?messageID=316228
Found information for WebLogic, but they talk about doing it programmaticly and not with configuration:
http://weblogic-wonders.com/weblogic/2010/06/12/binding-objects-in-weblogic-servers-jndi-tree/
http://forums.oracle.com/forums/thread.jspa?messageID=4397353
For WebSphere you can actually set the default schema in your defined DataSource. It is a custom property called currentSchema. (ie, in V7 it is Resources > JDBC > Data sources > your data source name > Custom properties > currentSchema.
Otherwise you can use a Name Space Binding and define it there: (ie, in V7 it is Environment > Naming > Name Space Bindings. You can use JNDI to look this up if you don't want to programmatically set it in WebSphere.
Can't speak to JBoss and WebLogic as I haven't worked with them.
If you are using Hibernate, this is the property to add in persistence unit :
<property name="hibernate.default_schema" value="myschema" />
That is the prefix that JPA will insert for table names.
If you need something 'closer' to the AS Datasources definitions, you may inject some DB-specific SQL at DB connection time; for instance Oracle,
ALTER SESSION SET CURRENT_SCHEMA =
On JBoss, you may add this in the datasource definition :
<new-connection-sql>
ALTER SESSION SET CURRENT_SCHEMA=myschema
</new-connection-sql>
Also editable in JBoss 7 Admin.
On Weblogic, you may inject this in the Connection Pools.
On Websphere, this should be similar.
On JBoss, you can use a special MBean(org.jboss.naming.JNDIBindingServiceMgr) and a service.xml to configure JNDI-entries, and then map these entries into your webapps. There is a lengthy explication for this rather non-trivial process here:
http://usna86-techbits.blogspot.com/2011/01/jboss-jndi-and-javacompenv.html
I'm still looking for a a way to place an entire properties-file/resourcebundle into jndi, as this manual mapping gets very tedious when you have a lot of properties that you want to put into jndi and make available for your webapps.
This same problem has been bothering be for quite a while for WebLogic, in particular 10.3.5 (11g).
I spent most of a day looking around and all I found was this: http://code.google.com/p/weblogic-jndi-startup/. It works just fine. It is a little restrictive: it requires the object you want to add to JNDI to have a constructor with a single String parameter.
For what I needed, weblogic-jndi-startup didn't work, so I built on Roger's code and came up with this: https://bitbucket.org/phillip_green_idmworks/weblogic-jndi-custom-resource-configuration/. I have a write up for it at http://coder-in-training.blogspot.com/2012/03/weblogic-jndi-custom-resource.html

Categories