2013-04-27 3 views
5

Lassen Sie uns sagen, dass wir das folgende Stück Code haben:Entfernt eine neue Transaktion alle vorherigen Entitäten?

@Entity 
public class User { 
    @Id 
    private String name; 
    @OneToOne(cascade = CascadeType.ALL) 
    private Address address; 
    //getters and setters 
} 

@Entity 
public class Address { 
    @Id 
    private int id; 
    private String street; 
    //getters and setters 
} 

@Stateless 
//@Service 
public class UserLogicClass { 
    @PersistenceContext 
    //@Autowired 
    private EntityManager entityManager; 

    public void logicOnUser(User user) { 
     if(logicOnAddress(user.getAddress()) { 
      otherLogicOnUser(user); 
     } 
    } 

    public boolean logicOnAddress(Address address) { 
     // 
     entityManager.find(address);//address becomes managed 
     // 
    } 

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    //@Transactional(propagation = Propagation.REQUIRES_NEW) 
    public void otherLogicOnUser 
    // 
     entityManager.find(user);/*without annotation, user is not managed and address is managed, but with the transaction annotation is the address still managed?*/ 
    // 
    } 
} 

Die Frage beruht im Kommentar aus dem letzten Verfahren; Ich bin neugierig, was passiert, sowohl in Spring Fall und EJB Fall. Angenommen, Spring ist mit JTA-Transaktionen konfiguriert und jede Methode, die von dieser Klasse aufgerufen wird, startet eine neue Transaktion, genau wie in EJB.

Antwort

5

Es ist mehr eine Frage der JPA. Der EntityManager ist nicht auf die neue Transaktion propagiert, wenn Sie es machen erweitert:

@PersistenceContext(type = PersistenceContextType.EXTENDED) 
//@Autowired 
private EntityManager entityManager; 

Zitat aus der JPA 2.0 Spezifikationen:

Ein Container-gesteuerter Persistenz Kontext definiert werden kann, entweder eine Lebensdauer haben Dies ist abhängig von der PersistenceContextType, die angegeben wird, wenn der Entity Manager erstellt wird. Dies ist auf eine einzelne Transaktion oder eine erweiterte Lebensdauer von beschränkt, die sich über mehrere Transaktionen erstreckt. Diese Spezifikation bezieht sich auf solche Persistenzkontexte wie transaktionsspezifische Persistenzkontexte bzw. erweiterte Persistenzkontexte.

+0

Also, wenn der Typ erweitert festgelegt ist, innerhalb dieser Methode, eine neue Entität Manager erstellt wird, das hat keine verwalteten Einheiten? – m3th0dman

+1

Ja, genau. In der 'otherLogicOnUser'-Methode wird eine neue Transaktion erstellt und der Persistenzkontext sollte nicht weitergegeben werden, solange Sie ihn nicht erweitern. – dcernahoschi

+0

Die Verwendung eines erweiterten EntityManagers wurde für die Verwendung in Stateful EJBs entwickelt, ist nicht threadsicher und Konflikte im Persistenzkontext können auftreten, wenn eine Methode mit einem transaktionsbereichsbezogenen EntityManager eine Methode mit einem erweiterten EntityManager in derselben Transaktion aufruft. – German

5

Hinweis: Da dieser Mechanismus auf Proxies basiert, nur ‚externe‘ Methode in über die Proxy-Anrufe kommen wird abgefangen. Dies bedeutet, dass "Self-Invocation", d. H. Eine Methode innerhalb des Zielobjekts, die eine andere Methode des Zielobjekts aufruft, nicht zur tatsächlichen Transaktion zur Laufzeit führt, auch wenn die aufgerufene Methode mit @Transactional markiert ist!

otherLogicOnUser() wird im Zielobjekt aufgerufen.

Lesen Sie mehr: EJB Transactions in local method-calls