3

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?

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
John Rumpel
  • 4,535
  • 5
  • 34
  • 48

1 Answers1

6

@javax.transaction.Transactional is an interceptor binding introduced in Java EE 7. The proxy injected by CDI for your bean will intercept annotated method calls to wrap them in a transaction.

Interceptors do not work for private methods - I suppose that's the main problem with your example.

Harald Wellmann
  • 12,615
  • 4
  • 41
  • 63
  • 1
    Just a side question here. Is there a particular way to intercept all transactions managed by the container? For my application, I need to inject custom SQL queries in the start of every transaction. I can't find any documentation relating to this. Kind regards. – JulioHM Aug 11 '14 at 15:38