2011-11-17 2 views
6

See this questionJPA/Playでトランザクションがコミットされる前に、エンティティはどのようにIDを取得しますか?

トランザクションを手動でコミットすることなく、TXがコミットされる前に、その人はsave()メソッドを呼び出した後にIDを持っていることが判明しました。

データベースがIDフィールドの引き金となるのではありませんか?その場合、コミットする前にIDフィールドをどのように埋めることができますか? TXがコミットされる前にDBとの通信が行われますか?

答えて

9

はい、JPAはトランザクションコミット前にDBと通信することができます。つまり、明示的にEntityManager#flush()を呼び出すと発生します。

また、JPAプロバイダは、必要があると感じるたびにフラッシュ操作を行うことができます。ただし、JPAプロバイダは便宜上、トランザクションがコミットされるまでDB操作を遅延させます。

一部の自動IDジェネレータ戦略では、PK値を取得するためにデータベースにアクセスする必要があります(これまでのところ、IDENTITYという戦略が覚えている限り)。
逆に、TABLEまたはSEQUENCEジェネレータは、ID値を取得するためにDBをヒットする必要はありません。彼らはallocationSizeパラメータを使用して、DBテーブルまたはSEQUENCEにバッチのIDを問い合わせ、データベースとの更なる通信を行わずに新しいエンティティに与えます。

3

再生!

JPABase._save()ソースコードから、オブジェクトを保存するたびに、永続コンテキストをフラッシュして(データベースに変更を書き込み、生成されたIDを取得できるようにする) :私は知っている

if (!em().contains(this)) { 
    em().persist(this); 
    PlayPlugin.postEvent("JPASupport.objectPersisted", this); 
} 
// ... 
try { 
    em().flush(); 
} catch (PersistenceException e) { 
    // ... 
} 
0

として、それが持続しています前に、我々は(それが自動番だと仮定)オブジェクトのIDを取得することはできません。 私は個人的には、RDBMSが外部で行うべきものを外部に割り当てることは非常に危険だと思います。あなたはそれを呼び出すいけない場合

EntityManagerHelper.getEntityManager().flush(); 

は、オブジェクトが失われ、DBに保存することがカント:でBeginTransactionとコミットの間

+0

なぜですか? JPAはそれを処理します...そして、あなたがトランザクションをコミットするときに万が一IDが利用できなくなった場合、トランザクションが失敗することを認識している限り(何らかの理由で)、私はIDを早く使ってもOKだと思います。 – ripper234

0

、コール保存または更新方法の後に、あなたが使用する必要があります。

これを呼び出すと、そのオブジェクトのIDを取得します。

関連する問題