2

I'm learning persistence in Java following some tutorial.

I'm using Java EE 7 and Payara server.

I noticed that each uses a different method for persistence.

Examples:

  • simple

    @Stateless
    public class BookServiceBean implements BookService {
        @PersistenceContext
        private EntityManager em;
    
        public void createOrUpdate(Book book) {
            em.persist(book);
        }
        public void remove(Book book) {
            em.remove(book);
        }
    }
    
  • with flush(), this is used when validation strategy isn't set on "AUTO" in persistene.xml, right?

    @Stateless
    public class BookServiceBean implements BookService {
        @PersistenceContext
        private EntityManager em;
    
        public void createOrUpdate(Book book) {
            em.persist(book);
            em.flush();
        }
        public void remove(Book book) {
            em.remove(book);
            em.flush();
        }
    }
    
  • with transaction

    @Stateless
    public class BookServiceBean implements BookService {
        @PersistenceContext
        private EntityManager em;
    
        public void createOrUpdate(Book book) {
            utx.begin();
            em.persist(book);
            utx.commit();
        }
        public void remove(Book book) {
            utx.begin();
            em.remove(book);
            utx.commit();
        }
    }
    

When and why do I have to use the last one?

Is it necessary to use em.close() at the end of each method?

What are the good practices?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Marco
  • 169
  • 6
  • 19
  • You can use `javax.ejb.TransactionAttribute` annoatation check http://stackoverflow.com/a/6863264/916225 – seenukarthi Apr 16 '16 at 13:49
  • A stateless EJB is transactional by default. Starting and committing transactions explicitly, in the code, is precisely what stateless beans allow avoiding. So there's no reason to start and commit transaction in code. Let the container do that for you. – JB Nizet Apr 16 '16 at 15:36

1 Answers1

5

The first one, an EJB method without all that manual flush and transaction fuzz, is the canonical approach. A single EJB method call counts by default already as a single full transaction. The EJB container will transparently begin the transaction before the method is invoked and commit the transaction when the method returns (or rollback when an application exception is thrown from the method).

The manual flush in second example is unnecessary. Generally, you want to use em.flush() only when you're modifying an entity (i.e. making it "dirty") and want afterwards (indirectly) perform a SELECT on it within the very same transaction. It's rare, but there are real world use cases for it, generally when you'd like to SELECT a parent whose the dirty entity is a child of.

The manual transaction management in third example is totally unnecessary. You should already realize that after having read the first paragraph. Manual transaction management is only necessary when you aren't using JTA, but RESOURCE_LOCAL (usually, in Java SE not Java EE).

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 1
    Note that even when the persistence context is dirty, the JPA engine is supposed to flush before executing a query whose results might depend on the dirty entities. I've seen a bug with that mechanism in a very specific case with Hibernate, but in general, its not necessary. – JB Nizet Apr 16 '16 at 15:44
  • Indeed, I recall Hibernate-related bugs which could only be workarounded with an explicit flush. – BalusC Apr 16 '16 at 15:51