我有以下服务......
@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则不会刷新。通过把冲洗我得到我需要的是正确的吗?
答案 0 :(得分:7)
不要将冲洗与提交混淆。在flush()
期间,JPA提供程序将生成的SQL物理地发送到数据库,在您的情况下,读取生成的ID并将其填充到bean中。 请注意,您应始终使用返回的实体而不是传递给 persist()
的原始实体:
token = em.persist(token);
击> <击> 撞击>
另一方面,提交执行数据库提交。显然它会首先触发flush()
,但这对你没有帮助。但是,因为您要问 - EJB中的每个方法都是默认的事务性。这意味着当您将第一个EJB留在堆栈上时会提交事务:如果从另一个EJB调用一个EJB,则默认情况下callee会加入调用者事务(请参阅:事务传播行为)。
另请注意,到flush()
的时间规则有点复杂,因为每个提供商都会尝试尽可能晚地批量执行此操作。