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 (使用数据库生成序列)虽然我知道如果我返回 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要将刷新与提交混淆。在
flush()
期间,JPA 提供程序将生成的 SQL 物理发送到数据库,并且在您的情况下,读取生成的 ID 并将其填充到 bean 中。请注意,您应该始终使用返回的实体,而不是传递给persist()
的原始实体:另一方面,提交执行数据库犯罪。显然它会首先触发
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 topersist()
: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.