EntityManager什么时候提交?

发布于 2024-12-12 02:12:24 字数 672 浏览 0 评论 0原文

我有以下服务...

@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 (使用数据库生成序列)虽然我知道如果我返回 Token 而不是字符串到调用服务id已设置。因此,当服务返回令牌对象时,EM 似乎会刷新,但当我将 String.通过冲洗我得到了我需要的东西,对吗?

I have the following service...

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

If I do not put em.flush() then the line token.getId() will return null (Using DB GENERATED SEQUENCE) though I know if I return Token instead of string to the calling service the id is set. So it seems that EM flushes when the service returns a token object but not when I put String. By putting flush I get what I need is that right though?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

指尖上的星空 2024-12-19 02:12:24

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

token = em.persist(token);

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

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

Do not confuse flushing with committing. During flush() JPA provider physically sends generated SQL to the database and, in your case, reads the generated ID and populates it in the bean. Note that you should always use the returned entity rather than the original one passed to persist():

token = em.persist(token);

Committing, on the other hand, performs database commit. Obviously it will trigger flush() first, but it won't help you here. But since you are asking - every method in EJB is transactional by default. This means the transaction is committed when you leave the first EJB on the stack: if you call one EJB from another, the callee joins the caller transaction by default (see: transaction propagation behaviour).

Also note that the rules when to flush() are a bit complicated since every provider tries to do this as late as possible and in batches.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文