How to use JDBC ClientInfo with JPA and EJB3 - java

We are migrating a JDBC based application to JPA and EJB3. Our old application used the Connect#setClientInfo API to record the current user name as part of the client info:
http://download.oracle.com/javase/6/docs/api/java/sql/Connection.html#setClientInfo%28java.lang.String,%20java.lang.String%29
We need to do something similar in the EJB3 project. How?
We can use EJB3 interceptors around the EJB service calls in order to capture the current user and set it as info on the datasource. However, I see problems with this. I think there is no guarantee when the JPA flush() occurs. If you set the client info in an interceptor, make some updates, and then return, the flush() and actual database write may not occur until well after your bean (and interceptor) are out of scope. Is this correct?
I believe JPA and EntityManagers are abstractions over the connection, and you cannot reliable set the client info on the connection. True or false?

What JPA provider are you using?
EclipseLink has support for user based connection, Oracle proxy connections and VPD. EclipseLink also defines Session and connection level events that allow you to set configuration on the JDBC connection.
See,
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Auditing

Related

Transactions in Enterprise level application

I am trying to understand the transactions, and more specifically i am doing it using Spring framework. Going through the material that i have (both internet and books), i see these terminologies:
Container managed transactions (CMT).
Bean Managed transactions (BMT).
Java transaction API (JTA).
Also, for a large enterprise level application, terminologies like "local" and "global" transactions too i have encountered.
What i have understood, is that global transactions is for the cases in which we are managing two or more different resouces (like One Oracle DB, other MySQL etc) and commits/rollback to them happen if both are success/failure. Local transactions is for when we have only one resource to manage (like only one DB connection to MySQL).
I have following doubts:
While writing a simple JDBC standalone program, we can code to commit/rollback. I believe this is example of local transaction, is this correct? And is this transaction taken care by "JDBC" library itself or the drivers?
What is CMT? What i understand is that Container takes care of the transaction management (like Jboss AS). If this is correct, how internally does it manages? Are CMT local or global? Do they use JDBC API's internally to manage the transactions?
What is BMT? This i am not able to understand. We can have application deployed in an App server (and i believe in those cases the transaction would be managed by Container) or i can write an standalone application in which i can use the transaction management code myself (try .. catch block etc). So, which category BMT falls?
While reading Spring framework, i read that Spring framework have its own way of managing the transaction. Down the line, i read Spring Framework uses JTA to manage transactions? I am confused about this. If JTA is API, do we have multiple vendors who implement JTA (like for JPA, we can have multiple vendors who provide the implementation e.g. Hibernate).
Is JTA for local or global transactions? When i write a simple JDBC program to manage transaction, does it use API's which comply JTA? Or is JTA totally different from transaction management which simple JDBC program uses?
Same for CMT, does CMT follow the rules which JTA has in place (the API's primarily)?
It would be great if you answer point-wise, i did search on net, my doubts are still not answered.
Concerning local/global transaction: by global I suppose you are talking about XA transaction (2 phase commits : http://en.wikipedia.org/wiki/X/Open_XA). This is just mandatory when you deal with multiple databases or transactionnal resources.
yes it's a "local transaction", it means only one database is
part of the transaction. The transaction is managed by the database
and controlled by JDBC in that case.
CMT : Container Managed: the container will detect the start and
the end of the transaction and will perform commit/rollback
depending on method return status (successfull return : commit,
exception : rollback). CMT rely on JTA to manage transactions on its
resources. Then it's up to the proper resource adapters (RA) to talk
to jdbc or any other drivers related to your EIS (data). Look at
http://docs.oracle.com/javaee/5/tutorial/doc/bncjx.html
BMT: it means it's up to the bean to control transaction
boundaries. It's pretty rare to use this kind of transaction
management these days. With BMT you control the UserTransaction
object, it's an error to control transaction boundaries directly
with JDBC. Bear in mind also that even if you are in BMT some
framework like JPA (not JTA) will invalidate current transaction on
any error even if you did not explicitely requested a rollback. It
means it's quite hard/dangerous/useless to use BMT.
JTA (I hope you did not mispelled JPA) is at another level: JTA
the API a resource adapter must implement to be part of a container
transaction. Apart from UserTransaction class (what you'll use in
BMT to control transaction boundaries) you have nothing to do with
JTA. There is no multiple implementation of JTA but there is multiple implementation of JTS (Java Transaction Service), each application server vendor implements their own JTS.
JTA is a API for framework designer, JTA impose a contract to the
Resource Adapter RA, and the RA will use JDBC or any other API to
deal with it's EIS (Enterprise Information Storage, let's call it
your DB). JTA works for XA and non XA transactions (if your RA supports XA transactions).
CMT uses JTA, but again JTA is a lowlevel contract between
components of the application server. Application designer should
not care about JTA.

Spring Roo - Bypass Hibernate

I have a Spring/Roo application which uses PostgreSQL and Hibernate.
As is appropriate, the connection information is located in the database properties file
src/main/resources/META-INF/spring/database.properties
Unfortunately, I have a situation where querying the database through Hibernate is draining the resources too much. I am sure that I can extract the database information (url/username/password) from the file listed above, but I am not sure where to begin my search.
Is there a manual or otherwise where I can find this information?
If you wish to bypass Hibernate to write more efficient queries by hand, you don't have to make separate connections to do it, and should not do so.
Get a Hibernate session and unwrap it to get the underlying java.sql.Connection. Or use native SQL via Hibernate's own interfaces.
That way you still get to use the useful bits of Hibernate, like the connection pooling integration. Sharing the same connection pool as Hibernate will improve efficiency, and you'll have a lot less extra code if you do it this way.
I haven't used Spring Roo, so I can't speak specifically for it. Here's info for Hibernate used via JPA or here. For direct Hibernate usage where you have a Session object, use Session.connection() on old versions of Hibernate, or the Work interface on newer versions:
Session.doWork()
session.connection() deprecated on Hibernate?
How to get jdbc connection from hibernate session?
Alternative of deprecated hibernate getSession().connection()
If you insist on doing this by hand anyway, start with ClassLoader.getResource(...).

EJB and Hibernate in Struts application

I have an application that has a struts 1.1 and EJB 2 combination, but now we are introducing a new piece into it with hibernate 3.2. The hibernate DAO's run in parallel with the EJB 2 session bean DAO's with pure JDBC. I am concerned about the jdbc connections management in this case. Since EJB 2.0 has container managed connections and transactions. But in the case of hibernate we begin and commit a hibernate transaction, Will it be safe to assume there will not be any issues with this architecture.
Need some analysis help.
PM
I was contemplating on the same issue, if hibernate module which might access existing tables being used by JDBC DAO's whose transaction is managed by Session Beans. But here is my approach:
I will have a delegate that invokes the EJB session bean, and since this bean will be responsible to manage transactions, I will create my hibernate DAO's and invoke them from this session bean, which I assume will not have any issues.
The hibernate session factory for this application will be instantiated once using the hibernate plugin that will be part of the struts config xml and will be saved as part of the servlet context and then the action class will pass this sessionfactory instance from the EJB session bean delegate to the hibernate DAO.
I guess this will be a clean approach, since the transaction will be managed by the EJB Session bean which are deployed onto the websphere. The JDBC connection pools management since is configured on the websphere and being accessed using the datasources, hibernate does not have to worry about this.
Please help me if I am on the right path with my assumptions ?
Transactions demarcate logical unit of work and hence are inherently isolated. But I am wondering why you need a combination of both. If you are already using EJB2 + JDBC why not stick to this?
Hibernate can be used without any problem with CMT (or BMT) session beans, share a connection pool with JDBC code and participate in the same transaction.
See the whole section 11.2. Database transaction demarcation and in particular 11.2.2. Using JTA.
What is not clear is if the Hibernate module will be "isolated" from the entities managed via JDBC. If you'll access the same tables via both APIs, you'll have to take some precautions:
don't expect to mix JDBC entities in a graph of Hibernate entities (the inverse is possible though).
respect and mimic Hibernate optimistic concurrency strategy when updating rows via JDBC
bypassing Hibernate's API won't trigger any cache update (if you're using the 2nd level cache) in which case you'd have to trigger it yourself.
Here is one of the possible solutions
A common JNDI Datasource, which will be used both in EJB's and Hibernate.

How to wrap an object change in my own transaction and incorporate it with Hibernate to JTA?

I have a web-app, which I deploy on Tomcat 6 and it uses Hibernate.
It receives messages on a JMS queue which trigger changes both to my DB, via Hibernate and to an Object of mine (Agent).
The web-requests also access the DB, via Hibernate, and access the shared object (there's a ConcurrentHashMap<AgentId,Agent> held by a singleton).
My problem is that I have a JMS message which changes several different Agents and several tables and I need the changes in the Agents to be available if and only if the DB transaction completed successfully. In addition I do not want to employ read locks as that is too much of a performance hazard for me.
I was thinking of somehow implementing the XAResource interface for my singleton and then use JTA to manage both my singleton and my Hibernate transaction.
What do you think? Does it sound reasonable? Am I way off?
If any additional details are needed please don't hesitate to ask
Ittai
Instead of implementing XAResource, you could use a transactional cache like EHCache which supports JTA since 2.0 (i.e. it can act as an XA resource and participate in a XA transaction alongside other XA resources).

When using spring and hibernate, how are sessions/transactions handled?

when using hibernate with spring, can someone explain how the session unit of work and transactions are handled?
is the transaction started at the beginning of the page request, and committed at the end?
can I have multiple db calls per request, that each have different transaction levels? e.g. some are left as default, while others are read-uncommitted?
is the transaction started at the beginning of the page request, and committed at the end?
In a web application, opening / closing the Session is usually done using the "Open Session in View" pattern. Spring comes with a OpenSessionInViewFilter or an OpenSessionInViewInterceptor for this. Both make Hibernate Sessions available via the current thread, which will be autodetected by transaction managers. It is suitable for service layer transactions via HibernateTransactionManager or JtaTransactionManager as well as for non-transactional execution (if configured appropriately).
Transaction demarcation is usually done at the service methods level, using Spring AOP to wrap them inside transactions.
can I have multiple db calls per request, that each have different transaction levels? e.g. some are left as default, while others are read-uncommitted?
You can have nested transactions with different isolation levels. Refer to the Transaction Management chapter.
It's usually configured declaratively with aspect oriented programming (AOP). You can define what beans, classes, packages or methods require transactions and Spring will provide it in a fashion similar to EJBs. Thanks to AOP you have full control over what exactly and how is wrapped into transactions.
Read more about it here: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative
to your questions:
1-is the transaction started at the
beginning of the page request, and
committed at the end?
Not exactly. the usual workflow of spring MVC is:
requestDispatcher->Controller->Service call(transaction starts and ends here)
Services may invoke Daos, Daos will talk to Datastore via Hibernate.
A transaction can continue living after the http response. e.g. service run in a thread.
2-can I have multiple db calls per
request, that each have different
transaction levels? e.g. some are left
as default, while others are
read-uncommitted?
Yes certainly you can.
let's say, your application does a migration job. a request says "start migration!" Then your service will read data via source database, and do some magic base on your migration logic, finally write to target database, and commit the transaction.

Categories