0

Actually I want to migrate a Seam 2 application to Java EE 7 with CDI and are trying to imitate the behavior of the Seam Home Component.

I am creating a application-managed EntityManager with a CDI producer and want to use it in a @ConversationScoped bean. I have defined my own EntityManager as a serializable wrapper around the default EntityManager implementation, which is just calling the methods of the delegate. The CDI producer looks as follows:

@ApplicationScoped
public class EntityManagerProducer
{
    @PersistenceUnit(unitName = "showcase")
    private EntityManagerFactory emFactory;

    @Produces
    @RequestScoped
    public EntityManager createEntityManager()
    {
        return new ExtendedEntityManager(emFactory.createEntityManager());
    }

    public void dispose(@Disposes final EntityManager entityManager)
    {
        if (entityManager.isOpen())
        {
            entityManager.close();
        }
    }
}

Do I need to define my conversationscoped Home component as @Stateful? An entity which was loaded by findon the injected entity manager is in a second step of the conversation not longer managed. A call of joinTransactiondoes not reattach the entity to the current EntityManager.

Edit:

I want to give some more information about the use case I am facing: As mentioned I want to imitate the Home component of Seam 2. So I created a own Home super class with CRUD methods for creating, updating and removing an entity. In the method for updating an entity I use following code:

public String update()
{
    try
    {
        joinTransaction();
        E tmp = getEntityManager().merge(getInstance());

        setInstance(tmp);
        getEntityManager().flush();

        // updatedMessage();
        // raiseAfterTransactionSuccessEvent();
    }
    catch (Exception ex)
    {
        log.error("error occured: ", ex);
    }
    return "updated";
}

public void joinTransaction() {
    log.debug("joining transation if EntityManager is open and not joined");
    if (getEntityManager().isOpen() && !getEntityManager().isJoinedToTransaction())
    {
        log.debug("joining transaction");
        getEntityManager().joinTransaction();
    }
}

If I call joinTransaction I can see in the log that getEntityManager().joinTransaction() is called. But this gives me the exception:

javax.persistence.TransactionRequiredException: Explicitly joining a JTA transaction requires a JTA transaction be currently activ

If I comment the line jooinTransaction() I'll get the following exception on the method call getEntityManager().flush():

javax.persistence.TransactionRequiredException: no transaction is in progress

So the problem is, that I would like to call flush and only then the entity should be persisted in database.

4

0 回答 0