ConversationScoped EntityManager

时间:2017-11-10 15:59:50

标签: java-ee cdi conversation-scope

实际上我想将Seam 2应用程序迁移到带有CDI的Java EE 7,并试图模仿Seam Home Component的行为。

我正在使用CDI生产者创建应用程序管理的EntityManager,并希望在@ConversationScoped bean中使用它。我已经将我自己的EntityManager定义为默认的EntityManager实现的可序列化包装器,它只是调用委托的方法。 CDI制作人看起来如下:

@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();
        }
    }
}

我是否需要将conversationscoped主页组件定义为@Stateful?在注入的实体管理器上由find加载的实体处于对话的第二步,不再受管理。调用joinTransaction不会将实体重新附加到当前的EntityManager。

编辑:

我想提供一些有关我面临的用例的更多信息: 如上所述,我想模仿Seam 2的Home组件。所以我用CRUD方法创建了一个自己的Home超类,用于创建,更新和删除实体。在更新实体的方法中,我使用以下代码:

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();
    }
}

如果我调用joinTransaction,我可以在日志中看到getEntityManager().joinTransaction()被调用。但这给了我一个例外:

  

javax.persistence.TransactionRequiredException:显式加入JTA事务需要当前激活JTA事务

如果我对该行jooinTransaction()发表评论,我将在方法调用getEntityManager().flush()上获得以下异常:

  

javax.persistence.TransactionRequiredException:没有正在进行的事务

所以问题是,我想调用flush,然后才能将实体保存在数据库中。

0 个答案:

没有答案