Статьи

Pre Java EE 7 альтернатива несинхронизированному контексту сохранения JPA 2.1

Несинхронизированный контекст персистентности в Java EE 7

В JPA 2.1 была введена концепция несинхронизированного контекста персистентности, которая позволяет детально контролировать сброс JPA Entity Manager, т. Е. Явно вызывая EntityManager # joinTransaction . Ранее это было по умолчанию до конца транзакции JTA, например, в типичном EJB без сохранения состояния менеджер сущностей сбрасывал бы свое состояние в БД в конце метода (который по умолчанию запускает и заканчивает транзакцию). Вы можете прочитать больше об этом здесь и здесь .

Возможно и в эпоху до Java EE 7 (как EE 5, так и EE 6)

Java EE 5 и 6 могут быть настроены так, чтобы достичь того же результата, который достигается в Unsynchronized Persistence Context в Java EE 7

Представьте себе случай использования, когда сведения о клиенте редактируются последовательно (с использованием мастера, такого как поток), например, информация об адресе на экране 1, информация о контакте на экране 2 и т. Д. Вы хотели бы сохранить состояние каждой категории, как и когда клиент вводит, но не хочет выдвигать все состояние в БД до тех пор, пока процесс не будет завершен, т.е. информация для всех категорий вводится пользователем

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
  }
 
}

Комментарии к коду говорят сами за себя (надеюсь)

Ура!