How to use JPA from a JBoss Web application ?

In simple terms, if you are not using EJB or CDI, the user is expected to interact with javax.transaction.UserTransaction which defines the transaction boundaries.

Here is an example Servlet which persists an Entity by injecting the UserTransaction and adding the EntityManager via the @PersistenceContext annotation:

@WebServlet(name="JPAServlet", urlPatterns={"/jpademo"})
public class JPAServlet extends HttpServlet {
    private static final Logger LOG = Logger.getLogger(TestServlet.class);

    @Inject
    private UserTransaction txn;

    @PersistenceContext
    private EntityManager em;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            txn.begin();

            em.persist(new Customer(1, "John Smith"));

            txn.commit();
          } catch (NotSupportedException beginExceptions) {
              LOG.errorf(beginExceptions, "Cannot start transaction: '%s'", txn);
          } catch (SecurityException | IllegalStateException | RollbackException
                  | HeuristicMixedException | HeuristicRollbackException commitExceptions) {
              LOG.errorf(commitExceptions, "Cannot commit transaction: '%s'", txn);
          } catch (SystemException systemException) {
              LOG.errorf(systemException, "Unexpected error condition on work with transaction: '%s'", txn);
          }
    }
}

Aside from that, be aware that by default WildFly does not bind the Entity Manager factory to JNDI. However, you can explicitly configure this in the persistence.xml of your application by setting the jboss.entity.manager.factory.jndi.name hint. The value of that property should be the JNDI name to which the entity manager factory should be bound.

You can also bind a container managed (transaction scoped) entity manager to JNDI as well via the hint jboss.entity.manager.jndi.name

Here’s an example:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
   xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
        http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
   <persistence-unit name="myPU">
      <!-- If you are running in a production environment, add a managed
         data source, the example data source is just for proofs of concept! -->
      <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
      <properties>
         <!-- Bind entity manager factory to JNDI at java:jboss/myEntityManagerFactory -->
         <property name="jboss.entity.manager.factory.jndi.name" value="java:jboss/myEntityManagerFactory" />
         <property name="jboss.entity.manager.jndi.name" value="java:/myEntityManager"/>
       </properties>
</persistence-unit>
</persistence>

Thanks to the jboss.entity.manager.factory.jndi.name and jboss.entity.manager.jndi.name you can now directly lookup the Entity manager and commit transactions as follows:

public void createSomeEntityWithTransactionScopedEM(String name) {
    Context context = new InitialContext();
    javax.persistence.EntityManager entityManager = (javax.persistence.EntityManager) context.lookup("java:/myEntityManager");
    SomeEntity someEntity = new SomeEntity();
    someEntity.setName(name);    entityManager.persist(name);
}