Reputation: 43
My application uses Hibernate as JPA provider and JBOSS 6.1.0-final as server. And the transaction is CMT (Transaction type in my persistence.xml is JTA). As most tutorial suggests. transaction in a ejb method will be automatically committed if it ends without any exception. However, in my application, unless I use flush()
, the transaction won't be committed when ejb method ends successfully(e.g. inserting a record never push any data to the database). It is the same result in both stateless and stateful beans.
I try to use @TransactionAttribute(TransactionAttributeType.REQUIRED)
, but the result is also the same. Even using MANDATORY
annotation doesn't throw any exception, which suggest my ejb method is using a container managed transaction.
Code Fragement:
@Stateful
@Local
public class TransactionTest implements ITransactionTest {
@PersistenceContext(unitName="Table")
private EntityManager manager;
public void generateRecord(int i) throws RuntimeException{
Record record = new Record();
record.setId(i+"");
record.setStatus(1);
manager.persist(record);
manager.flush(); //without this, it won't commit
}
}
So, why my ejb method can't commit transaction automatically?
Upvotes: 2
Views: 4196
Reputation: 11602
Stateful session bean has PersistenceContextType.EXTENDED
by default.
5.6.1.2 Container-managed Extended Persistence Context
A container-managed extended persistence context exists from the point at which the container-managed entity manager has been obtained by dependency injection or through JNDI lookup until it is closed by the container. Such an extended persistence context can only be initiated within the scope of a stateful session bean and is closed by the container when the @Remove method of the stateful session bean completes (or the stateful session bean instance is otherwise destroyed).
When an extended persistence context is used, the entities managed by the EntityManager remain managed independently of whether JTA transactions are begun or committed. They do not become detached until the persistence context ends.
You can try TransactionAttributeType.REQUIRES_NEW
, therefore commit is called after exiting from the method. Flush automatically gets called before commit.
If you want to commit changes right away, you can try changing the transaction attribute, which will be part of a separate new transaction.
If you don't want to commit changes & needs single transaction to propagate , then your current approach is fine & call flush explicitly.
Upvotes: 1