Transactional call to Spring from legacy code - java

We have a legacy JEE-application with a modernized spring core. Sometimes, calls are made from the JEE part into Spring. When deployed on the JEE-Server, a configured JTA-Transactionmanager handles the transactional issues sufficiently.
In integration tests outside a real JEE-Container this is not the case. When we start a transaction outside the Spring core and call a #Transactional method from within the core, the transaction gets used all-right but after terminating the #Transactional method, Spring commits the transaction (a behaviour not seen when using JTA).
Is there any way to configure Spring such that #Transactional checks for a running transaction and only terminates transactions it opend itself?

Related

How to set-up transactions for both the web application and batch jobs using Spring and Hibernate

I have an application which uses Spring 4.3 and Hibernate 5.3.
There's a web application with a presentation layer, a servive layer and a DAO layer, as well as some jobs sharing the same service and DAO layers.
Transactions are initialized in different layers with #Transactional annotations.
It led me to a problem I described here: Controlling inner transaction settings from outer transaction with Spring 4.3
I read a bit about how to set-up transactions to wire Spring and Hibernate together. It looks the recommended approach is to initialize transactions in the service layer.
What I don't like is that most transactions exist only because they are required for hibernate to work properly.
And when I really need a transaction for a job calling multiple service methods, it seems I don't have a choice to keep initializing transactions from the jobs. So moving #Transactional annotations from DAO to service doesn't seem to make any difference.
How would you recommend to set-up transactions for this kind of application?
Pardon me for replying in answer as I am not able to comment
I don't get the meaning of you having to keep initializing transactions from the jobs?
Usually for
DAO class, it should be annotated with #Repository.
Service class with #Service and #Transactional
Webservice, if u have, with #RestController, #RequestMapping, #Transactional.
By doing so, any call from service class will be 1 transaction thus if Service class A calls service B and C, even if service class C throws error, the whole transactions will be rollback.

EJB 3.0 Transaction propagation

With respect to EJB 3.0 transaction propagation, I have the following basic question.
This is my scenario : EJB Service -> POJO -> EJB Dao. I need to stick to this architecture due to some constraints within the organization.
So, in EJB Service Tx starts, I direct to a POJO which returns the local EJB DAO. Now within the methods of the EJB DAO, I inject the persistence context and the Entity Manager and the methods have been annotated with TransactionAttribute (Required). So my question is if within the DAO EJB will the transaction context of the Service EJB be used or will it start a new transaction due to the POJO layer in between.
Any help would be appreciated.
Thanks..Vijay
Since a transaction is started from the "EJB Service", it will be propagated to the "EJB DAO". The transaction is set as a kind of thread local (at least conceptually, I don't know how implementations do it). That is unless the POJO does anything like running the DAO in a newlly created thread (which -for manually created threads- is inappropriate for Java EE anyway).

Porting my hibernate Dao layer in a stand-alone java app?

I have a spring mvc application that I am using Hibernate with.
I am using the sessionFactory.getCurrentSession in my Dao methods (not hibernate support).
What I want to know is, what do I have to do to be able to use my hibernate database layer
in a non-web application?
I have a stand-alone java application (that runs via main) where I load spring's application context
programatically and then get my service layer (which depends on my hibernate db layer).
Do I need to do anything special in my spring.xml file to setup hibernate's session?
In my spring mvc web app, I did annotate my Dao methods with the #Transactional annotation.
(I want the transaction on a per call basis, not for a group of db calls).
P.S In my web app, how are sessions created/destroyed, is it per request?
You can get hold of the spring ApplicationContext from main method. it will behave exactly the same as the one in web.
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
YourDAO yDao = (YourDAO)context.getBean("yourDAO");
yDao.callYourSpecialMethod();
So, from this point there is no dependancy for hibernate, it should work automatically. here just the view gets changed, no logical or structural changes. So the transactions and other things should work as usual.

Application vs Container Managed EntityManager

I am currently having a problem with understanding a concept of JPA.
I am currently using/developing recent EclipseLink, Glassfish, Derby database to demonstrate a project.
Before I develop something in much bigger picture, I need to be absolutely sure of how this PersistingUnit work in terms of different scopes.
I have bunch of servlets 3.0 and currently saving user's associated entity classes in the request.session object (everything in the same war file). I am currently using Application-managed EntityManager using EntityManagerFactory and UserTransaction injection. It works smooth when it is tested by myself. The different versions of entities occur when 2 people accessing the same entities at the same time. I want to work with managed beans cross the same WAR, same persistence unit if possible.
I have read http://docs.oracle.com/javaee/6/tutorial/doc/bnbqw.html and bunch of explanations of those scopes which don't make sense at all for me.
Long story short, what are the usage and difference of app and container managed EntityManagers?
When you say application managed transaction it means its your code which is supposed to handle the transaction. In a nutshell it means:
You call:
entityManager.getTransaction().begin(); //to start a transaction
then if success you will ensure to call
entityManager.getTranasaction().commit(); //to commit changes to database
or in case of failure you will make sure to call:
entityManager.getTransaction().rollBack();
Now imagine you have a container, which knows when to call begin(), commit() or rollback(), thats container managed transaction. Someone taking care of transaction on your behalf.
You just need to specify that.
Container managed transaction(CMT) could be regarded as a kind of declarative transaction, in which case, transaction management is delegated to container (normally EJB container), and much development work could be simplified.
If we are in a Java EE environment with an EJB container, we could use CMT directly.
If we are in a Java SE environment, or a Java EE environment without an EJB container, we could still take advantage of CMT, one way is to use Spring, which uses AOP to implement declarative transaction management; Another way is to use Guice, which uses a PersistFilter to implement declarative transaction.
In CMT, a container (whatever an EJB container, Spring or Guice) will take care of the transaction propagation and commit/rollback stuff;
Application managed transaction (AMT) differs from CMT in that we need to handle transactions programmatically in our code.

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