EntityManager何时提交?

use*_*024 4 jpa jersey entitymanager ejb-3.1

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

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Tom*_*icz 7

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

token = em.persist(token);
Run Code Online (Sandbox Code Playgroud)

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

另请注意,规则何时flush()有点复杂,因为每个提供程序都尝试尽可能晚地批量执行此操作.