Search code examples
jpaejbjtatransactional

does find query return managed or detached entities in JTA transactions?


In the following class, both the methods return the same objects.

But is the list of objects returned from first is managed since it is part of transaction when compared to second one which is not part of transaction?

public class QueryServiceImpl implements QueryService { 
    @PersistenceContext(unitName="PC") 
    EntityManager em; 

   //default attribute
   @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    public List findAlItems() { 
        return em.createQuery("SELECT item FROM Item item",  
                              Item.class) 
                 .getResultList(); 
    } 


    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
    public List findAlItemsNoTransaction() { 
        return em.createQuery("SELECT item FROM Item item",  
                              Item.class) 
                 .getResultList(); 
    } 

Solution

  • Regarding your example, you're right. All entities should not be managed after returning from the second method (findAlItemsNoTransaction). However, if you would like to keep them managed you should use:

    @PersistenceContext(type=EXTENDED) 
    

    like it was showed in JPA specification:

    /*
    * An extended transaction context is used. The entities remain
    * managed in the persistence context across multiple transactions.
    */
    
    @Stateful
    @Transaction(REQUIRES_NEW)
    public class ShoppingCartImpl implements ShoppingCart {
        @PersistenceContext(type=EXTENDED)
        EntityManager em;
        private Order order;
        private Product product;
        public void initOrder(Long id) {
            order = em.find(Order.class, id);
        }
    
        public void initProduct(String name) {
            product = (Product) em.createQuery("select p from Product p 
                    where p.name = :name")
                    .setParameter("name", name)
                    .getSingleResult();
        }
        public LineItem createLineItem(int quantity) {
            LineItem li = new LineItem(order, product, quantity);
            order.getLineItems().add(li);
            em.persist(li);
            return li;
        }
    }