Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Application managed JPA, when is Transaction needed

Tags:

java

jpa

jpa-2.0

We are working on a little web (will run on Tomcat) with the data layer done with JPA (Eclipselink). I did similar thing some time ago. But i were always unsure when i need to begin and end transactions or do a flush. At the moment i use transaction if i add (persist) and remove objects. If i call setters on an already persisted object i do not use transactions.

Is there a guide/ tutorial or a short answer when to use transactions or how to implement application managed JPA correctly.

like image 496
dermoritz Avatar asked Feb 10 '14 08:02

dermoritz


People also ask

What is @transactional used for?

The @Transactional annotation is the metadata that specifies the semantics of the transactions on a method. We have two ways to rollback a transaction: declarative and programmatic. In the declarative approach, we annotate the methods with the @Transactional annotation.

How are transactions managed in JPA?

JPA and Hibernate transaction management Once a JPA transaction has started, any entity bean that interacts with the EnityManager -- be it through a persist, merge or delete method call -- will have its state managed by Hibernate until the transaction commits.

What is a transaction in JPA?

An object level transaction is one in which a set of changes made to a set of objects are committed to the database as a single unit. JPA provides two mechanisms for transactions. When used in Java EE JPA provides integration with JTA (Java Transaction API).

How are transactions handled in Spring data JPA?

Spring Boot and Spring Data JPA make the handling of transactions extremely simple. They enable you to declare your preferred transaction handling and provide seamless integration with Hibernate and JPA. The only thing you need to do is to annotate one of your methods with @Transactional.


1 Answers

I think one can summarize an answer to your question. almost any JPA operation needs a transaction, except find/selects that do not lock entities (i.e any JPA operation that does not change the data).

(JTA transaction-scoped entity manager) In the case of an JTA transaction-scoped entity manager it is better to quote from the spec (Chapter 3 Entity Operations):

The persist, merge, remove, and refresh methods must be invoked within a transaction context when an entity manager with a transaction-scoped persistence context is used. If there is no transaction context, the javax.persistence.TransactionRequiredException is thrown.

Methods that specify a lock mode other than LockModeType.NONE must be invoked within a transaction context. If there is no transaction context, the javax.persistence.TransactionRequiredException is thrown.

The find method (provided it is invoked without a lock or invoked with LockModeType.NONE) and the getReference method are not required to be invoked within a transaction context. If an entity manager with transaction-scoped persistence context is in use, the resulting entities will be detached; if an entity manager with an extended persistence context is used, they will be managed. See section 3.3 for entity manager use outside a transaction.

(Application-managed/resource-local entity manager) In the case of an Application-managed entity manager, the JPA spec is not clear about the behavior. In the case of Hibernate, it is pretty complicated what happens, when not inside a transaction (it could depend also on the JDBC driver and the autocommit mode of the DB connection). Check Hibernate's article on this theme. Basically you are strongly encouraged to always use transactions for the above mentioned operations.

To the second part of your question: if you called a setter of a managed entity, and without flushing you detached it (i.e before transaction commit), the behavior is unclear/undefined, i.e you should better correct the code.

Example of buggy code:

//begin Transaction
MyEntity entity = em.find(MyEntity.class, 1L);
entity.setField("New value");
em.detach();//it is not sure whether the "New value" will be persisted. To make sure it is persisted, ypu need to call em.flush() before detaching
//commit Transaction

Usually if the order of DB operations (not the same as the order of enity manager operations) is not important, you can leave the JPA implementation to decide when to flush (e.g on transaction commit).

like image 80
V G Avatar answered Nov 03 '22 01:11

V G