2011-10-26 9 views
4

私は以下のサービスを持っている...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は()(DB生成されたシーケンスを使用して)nullを返しますidが設定されている呼び出し側サービスに文字列の代わりにトークン。だから、EMは、サービスがトークンオブジェクトを返すときにフラッシュするようですが、Stringを置いたときにはフラッシュしません。私が必要としているものを得るためには、それは正しいですか?

答えて

7

フラッシングとコミットを混同しないでください。 flush()の間に、JPAプロバイダは生成されたSQLをデータベースに物理的に送信し、場合によっては生成されたIDを読み取り、Beanに移入します。あなたは常にpersist()に渡されたオリジナルのものではなく、返されたエンティティを使用する必要があり 注:

token = em.persist(token); 

がコミット、一方で、データベースはコミットを実行します。明らかに最初にflush()がトリガーされますが、ここでは役に立ちません。しかし、あなたが尋ねているので、EJBのすべてのメソッドはデフォルトでトランザクションです。これは、最初のEJBをスタックに残すときにトランザクションがコミットされることを意味します。別のEJBから1つのEJBを呼び出すと、呼び出し元のトランザクションはデフォルトで結合されます(トランザクションの振舞いの振る舞いを参照)。

flush()のルールは、すべてのプロバイダができるだけ遅く、バッチでこれを実行しようとするため、少し複雑です。

+0

私はtoken = em.persist(token)と思われません。 Netbeans 7.0.1を使うと、これは最新のEJBでしかないと思いますか? – user432024

+1

私は悪いですが、 'persist()'ではなく、新しいインスタンスを返す 'merge()'です。それにもかかわらず、明示的に 'flush()'する必要があります。 –

+0

ありがとうございます。だから、私は上記のコードであなたの何があなたの場所で、またはより高いレベルで呼び出し元のフォーマットを行う必要がありますか? – user432024

関連する問題