Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a new transaction detach all previous entities?

Let's say we have the following piece of code:

@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?*/
    //
    }
}

The question relies in the comment from the last method; I am curios what happens in both Spring case and EJB case. Suppose Spring is configured with JTA transactions and any method called from this class would start a new transaction, just as in EJB.

like image 349
Random42 Avatar asked Apr 27 '13 06:04

Random42


People also ask

When the JPA entities will become detached?

When the transaction (in transaction-scoped persistence context) commits, entities managed by the persistence context become detached. If an application-managed persistence context is closed, all managed entities become detached. Using clear method.

How does the detach operation affect the entity object in new state?

If A is a detached entity, its state is copied into existing managed instance A' of the same entity identity, or a new managed copy of A is created. If A is a new entity, a new managed entity A' is created and the state of A is copied into A' . If A is an existing managed entity, it is ignored.

What is detach entity?

A detached entity (a.k.a. a detached object) is an object that has the same ID as an entity in the persistence store but that is no longer part of a persistence context (the scope of an EntityManager session).

How do you detach your entity from session before modifying its ID fields?

You can detach an entity by calling Session. evict() . Other options are create a defensive copy of your entity before translation of values, or use a DTO instead of the entity in that code.


2 Answers

It's more an issue of JPA. The entityManager is not propagated to the new transaction unless you make it extended:

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

Quote from the JPA 2.0 specs:

A container-managed persistence context may be defined to have either a lifetime that is scoped to a single transaction or an extended lifetime that spans multiple transactions, depending on the PersistenceContextType that is specified when its entity manager is created. This specification refers to such persistence contexts as transaction-scoped persistence contexts and extended persistence contexts respectively.

like image 123
dcernahoschi Avatar answered Sep 28 '22 07:09

dcernahoschi


Note: Since this mechanism is based on proxies, only 'external' method calls coming in through the proxy will be intercepted. This means that 'self-invocation', i.e. a method within the target object calling some other method of the target object, won't lead to an actual transaction at runtime even if the invoked method is marked with @Transactional!

otherLogicOnUser() is invoked inside target object.

Read more: EJB Transactions in local method-calls

like image 37
MariuszS Avatar answered Sep 28 '22 09:09

MariuszS