EntityManager何时提交?

时间:2011-10-26 15:20:52

标签: jpa jersey ejb-3.1 entitymanager

我有以下服务......

@Stateless
@LocalBean
public class RandomService {

    @EJB RandomString stringTokenizer;

    @PersistenceContext
    EntityManager em;

    public String generate(Actions action)
    {
        Token token = new Token();
        token.setAction(action);
        token.setExpiry(new Date());
        token.setToken(stringTokenizer.randomize());

        em.persist(token);
        //em.flush();

        return String.format("%010d", token.getId()) + token.getToken();
    }
}

如果我没有放入em.flush(),那么行token.getId()将返回null(使用DB GENERATED SEQUENCE)虽然我知道如果我将Token而不是string返回给调用服务,则设置id。因此,当服务返回令牌对象时,EM似乎会刷新,但是当我放置String时,EM则不会刷新。通过把冲洗我得到我需要的是正确的吗?

1 个答案:

答案 0 :(得分:7)

不要将冲洗与提交混淆。在flush()期间,JPA提供程序将生成的SQL物理地发送到数据库,在您的情况下,读取生成的ID并将其填充到bean中。 请注意,您应始终使用返回的实体而不是传递给persist()的原始实体:

token = em.persist(token);

<击>

另一方面,提交执行数据库提交。显然它会首先触发flush(),但这对你没有帮助。但是,因为您要问 - EJB中的每个方法都是默认的事务性。这意味着当您将第一个EJB留在堆栈上时会提交事务:如果从另一个EJB调用一个EJB,则默认情况下callee会加入调用者事务(请参阅:事务传播行为)。

另请注意,到flush()的时间规则有点复杂,因为每个提供商都会尝试尽可能晚地批量执行此操作。