Enterprise Java

Pre Java EE 7 alternative to JPA 2.1 unsynchronized persistence context

Unsynchronized persistence context in Java EE 7

JPA 2.1 introduced the concept of unsynchronized persistence context which allows fine grained control over flushing of the JPA Entity Manager i.e. by explicitly calling EntityManager#joinTransaction. Previously, this was defaulted to end of JTA transaction e.g. in a typical Stateless EJB, the entity manager would flush its state to the DB at the end of a method (which starts and ends a transaction by default). You can read more about this, here and here.

Possible in the pre Java EE 7 era as well (both EE 5 and EE 6)

Java EE 5 and 6 have can be tweaked to achieve the same result as attained by the Unsynchronized Persistence Context in Java EE 7

Imagine a use case where customer details are being edited in a sequential manner (using a wizard like flow) e.g. address info in screen 1, contact info in screen 2 etc. You would want to save the state of the each category as and when the customer enters is but do not wish to push the entire state to the DB until the process is complete i.e. info for all the categories is entered by the user

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.abhirockzz.conversationalee;
 
import com.abhirockzz.conversationalee.entity.Customer;
import java.util.Date;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
 
@Stateful
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class CustomerEditorFacade{
  
  @PersistenceContext(type = PersistenceContextType.EXTENDED)
  EntityManager em;
   
  @Inject //this won't work in Java EE 5
  Principal authenticatedUser;
   
  private Customer customer;
   
  @PostConstruct
  public void init(){
      System.out.println("CustomerEditorFacade created at " + new Date().toString());  
  }
   
  @PreDestroy
  public void destroy(){
      System.out.println("CustomerEditorFacade destroyed at " + new Date().toString());  
  }
   
  //step 1
  public void updateCity(String custID, String city){
    String custID = authenticatedUser.getName(); //assume we have an authenticated principal which is the same as the customer ID in the Database
    Customer customerFromDB = em.find(Customer.class, Integer.valueOf(custID)); //obtain a 'managed' entity
    customerFromDB.setCity(city); //no need to call em.persist
    customer = customerFromDB; //just switch references
     
    //Customer state will NOT be pushed to DB
  }
 
  //step 2
  public void updateEmail(String email){
    customer.setEmail(email); //not pushed to DB yet
  }
   
  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public void save(){
    //dummy method to trigger transaction and flush EM state to DB
  }
   
  @Remove
  public void finish(){
    //optional method to provide a way to evict this bean once used
    //not required if this is session scoped
  }
 
}

The code comments are self explanatory (hopefully)

Cheers!

Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy
Subscribe
Notify of
guest


This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button