Having a simple CDI bean in session scope with an entity manager injected:
@Named("myBean")
@SessionScoped
public class MyBean implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
EntityManager em;
...
@Transactional
private void testInsert() {
long t = System.currentTimeMillis();
for (int i=1; i<50000; i++) {
create(i);
}
System.out.println("Time: " + Long.toString(System.currentTimeMillis()-t));
}
private void create(int i) {
Project p = new Project("Project " + i);
em.persist(p);
}
}
Now, when calling the function via EL #{myBean.testInsert} there are two things that seems to be very strange:
1) Moving the @Transactional-annotation to the method create(int) I get:
javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
2) Decorating testInsert() with @Transactional instead, the function returns instantly but JPA is still updating the database within a background thread. The process needs 2 minutes to finish INSERT of only 50000 records. When shutting down the Java EE-application server within the process, the background process stops and thus - in my opinion - testInsert() is not transactional.
What is my general misunderstanding here? How to manage transactions properly?