JPAライフサイクルイベントを使用してエンティティデータを取得する方法

アブラハム:

@EntityListnersで注釈が付けられたエンティティークラスを利用するRESTful APIがあります。そして、EntityListner.javaには、@ PostPersistアノテーションが付けられたメソッドがあります。したがって、そのイベントが発生したときに、データベースに永続化されたエンティティに関するすべての情報を抽出したいと思います。しかし、それを実行しようとすると、Glassfishが例外を生成し、EntityListnerクラスのメソッドが期待どおりに実行されません。これがコードです

public class EntityListner {
private final static String QUEUE_NAME = "customer";
@PostUpdate
@PostPersist
public void notifyOther(Customer entity){
    CustomerFacadeREST custFacade = new CustomerFacadeREST(); 
    Integer customerId = entity.getCustomerId();
    String custData = custFacade.find(customerId).toString();
    String successMessage = "Entity added to server";
    try{
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
      //  channel.basicPublish("", QUEUE_NAME, null, successMessage .getBytes()); 
        channel.basicPublish("", QUEUE_NAME, null, custData.getBytes());  
        channel.close();
        connection.close();


    }
    catch(IOException ex){

    }
    finally{

    }
  }    
} 

custDataではなくコメント化されたsuccessMessageメッセージを送信すると、すべて正常に機能します。

http://www.objectdb.com/java/jpa/persistence/eventは、エンティティのライフサイクルメソッドに関して次のように述べています。それがここの状況なのかどうか疑問に思っています。

エンティティライフサイクルイベント(まだ進行中)を発生させる元のデータベース操作との競合を回避するために、コールバックメソッドはEntityManagerまたはQueryメソッドを呼び出さないでください。

何か案は?

gpeche:

その段落で述べているように、標準はエンティティリスナーの内部からのエンティティマネージャーメソッドの呼び出しをサポートしていません。Heiko Ruppが彼の答えで言っているように、永続化されたエンティティから構築することを強くお勧めcustDataします。それが不可能な場合は、以下を検討してください。

  • 非同期に通知します。これはおそらく適切に動作するタイミングに依存するため、これはあまりお勧めしません
public class EntityListener { 
    private final static String QUEUE_NAME = "customer"; 

    private ScheduledExecutorService getExecutorService(){ 
        //どこかから非同期エグゼキューターサービスを取得
        //多少の遅延で
        通知をスケジュールするには// 
        おそらく、ScheduledExecutorService インスタンスが必要になるでしょうまたは、
        通知する前にThread.sleep(...)//を試すこともできますが、これは醜い方法です。
    } 

    private void doNotifyOtherInNewTransaction(Customer entity){ 
        //これをすべて正しく機能させるには、
        // 
        新しいトランザクション内で// 通知を実行する必要がありますかもしれない
        //これを宣言的に実行する方が簡単です
        // // REQUIRES_NEWで
        区切られたいくつかのメソッドを呼び出すことで// 
        試行{ 
            //(トランザクションを開始)
            doNotifyOther(entity); 
            //(トランザクションのコミット)
        } catch(例外ex){ 
            //(ロールバックトランザクション)
        } 
    } 

    @PostUpdate 
    @PostPersist 
    public void notifyOther(final Customer entity){ 
        ScheduledExecutorService executor = getExecutorService(); 
        //これは「未加工」バージョンです
        //ほとんどの場合
        、executor.schedule を呼び出し、遅延を指定する必要があります。 
        、古いトランザクションに
        //フラッシュしてコミットする時間を与えるために、// 
        てexecutor.execute(新しいRunnableを(){ 
            @Override 
            ます。public void実行(){ 
                doNotifyOtherInNewTransaction(エンティティ); 
            } 
        }); 
    } 

    //これは、元のコードとまったく同じです
    。public void doNotifyOther(Customer entity){ 
        CustomerFacadeREST custFacade = new CustomerFacadeREST(); 
        整数customerId = entity.getCustomerId(); 
        文字列custData = custFacade.find(customerId).toString(); 
        String successMessage = "エンティティがサーバーに追加されました"; 
        {を試す
            ConnectionFactoryファクトリ=新しいConnectionFactory(); 
            factory.setHost( "localhost");
            接続connection = factory.newConnection(); 
            チャネルチャネル= connection.createChannel(); 
            channel.queueDeclare(QUEUE_NAME、false、false、false、null); 
            channel.basicPublish( ""、QUEUE_NAME、null、custData.getBytes());  
            channel.close(); 
            connection.close(); 
        } 
        catch(IOException ex){ 
        } 
        最後に{ 
        } 
    }     
}
  • コミット後のトリガーをいくつか登録します(Heilo Ruppの回答が不可能な場合の私の推奨事項)。データベースにフラッシュした後に実行されることが保証されているため、これはタイミングに依存しません。さらに、トランザクションをロールバックする場合に通知しないという利点もあります。これを行う方法は、トランザクション管理に何を使用しているかによって異なりますが、基本的には、特定のインスタンスのインスタンスを作成し、それをレジストリに登録します。たとえば、JTAでは次のようになります。
public class EntityListener { 
    private final static String QUEUE_NAME = "customer"; 

    private Transaction getTransaction(){ 
        //どこかから現在のJTAトランザクション参照を取得
    } 

    private void doNotifyOtherInNewTransaction(Customer entity){ 
        //これがすべて正しく機能するためには、
        // 
        新しいトランザクション内で// 通知を実行する必要があります
        //宣言的に
        // 
        REQUIRES_NEWで区切られたいくつかのメソッドを呼び出すことで// これを行う方が簡単かもしれません// 
        {{ 
            トランザクションを開始する)
            doNotifyOther(entity); 
            //(トランザクションをコミット)
         }キャッチ(例外ex){
            //(ロールバックトランザクション)
         } 
    } 

    @PostUpdate 
    @PostPersist 
    public void notifyOther(final Customer entity){ 
        Transaction transaction = getTransaction(); 
        transaction.registerSynchronization(新しい同期(){ 
            @Override 
            公共ボイドbeforeCompletion(){} 

            @Override 
            公共ボイドafterCompletion(INT状態){ 
                (ステータス== Status.STATUS_COMMITTED){もし
                    doNotifyOtherInNewTransaction(エンティティ); 
                } 
            } 
    //これは元のコードとまったく同じ 
        })。             
    } 

    public void doNotifyOther(Customer entity){ 
        CustomerFacadeREST custFacade = new CustomerFacadeREST(); 
        整数customerId = entity.getCustomerId(); 
        文字列custData = custFacade.find(customerId).toString(); 
        String successMessage = "エンティティがサーバーに追加されました"; 
        { 
            ConnectionFactory factory = new ConnectionFactory();を試してください 
            factory.setHost( "localhost"); 
            接続connection = factory.newConnection(); 
            チャネルチャネル= connection.createChannel(); 
            channel.queueDeclare(QUEUE_NAME、false、false、false、null); 
            channel.basicPublish( ""、QUEUE_NAME、null、custData。  
            channel.close(); 
            connection.close(); 
        }
        catch(IOException ex){ 
        } 
        最後に{ 
        } 
    }     
}

Springトランザクションを使用している場合、コードは非常によく似ており、クラス名がいくつか変更されています。

いくつかのポインタ:

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

インラインエディタを使用してDialogflowフルフィルメントでhttpリクエストをテストする方法

分類Dev

ラムダ式とlinqを使用して、EFを使用して別のエンティティモデルタイプのリストを含むエンティティモデルをデータベースに追加する方法

分類Dev

ウィンドウフォームのボタンクリックイベントを使用して、データテーブルに存在する行の総数を単一のラベルに取得する方法c#

分類Dev

GCPデータストアエンティティデータをcsvファイルにエクスポートする方法を探しています

分類Dev

アクティビティとフラグメント間のインターフェイスを使用して双方向にデータを送信する方法

分類Dev

データベースエンティティのインターフェイスとしてトレイトを使用する

分類Dev

ライフサイクルイベントをアクティブに正しく監視する方法

分類Dev

JPA2を使用してユーザータイプのフィールドを含むエンティティを永続化する方法

分類Dev

エンティティフレームワークを使用してデータベース内のレコードを更新するときにモデル検証をオーバーライドする方法

分類Dev

c#.netsdkを使用してデータファクトリパイプラインでkustoアクティビティを作成する方法

分類Dev

Bokeh:2つのインタラクティブウィジェットを使用してCustomJSでデータセットをフィルタリングする

分類Dev

JupyterLabを使用してインタラクティブなフィギュアをループで更新する方法

分類Dev

一連のクラスをjarライブラリからjpaエンティティにマップしてデータベーステーブルを作成する方法

分類Dev

curlwgetを使用してインタラクティブなhttpサイトからLinuxシェルにファイルをダウンロードする

分類Dev

インターフェイスリスナーを使用してアクティビティからフラグメントにデータを送信する

分類Dev

ReactでsetStateを使用してオブジェクトを更新する(ソリディティイベントフィルター)

分類Dev

TeamFoundationクライアントを使用してビルドアーティファクトから個々のファイルを取得する方法

分類Dev

データベースを使用したオフラインツールのベストプラクティス

分類Dev

タイマーティックイベントを取得して別の関数C ++ / CLIを中断する方法

分類Dev

インターフェイスを使用してアクティビティからフラグメントにコールバックを戻す方法

分類Dev

コマンドラインを介してEclipseでアクティブなエディターのファイルパスを取得します

分類Dev

クリティカルイベントとエラーイベントをCSVファイルにフィルターする

分類Dev

JPAネイティブクエリを使用してポイントタイプデータを更新するにはどうすればよいですか?

分類Dev

JPAエンティティをデータベース列を使用してJSONとしてフォーマットする方法は?

分類Dev

JPAエンティティをデータベース列を使用してJSONとしてフォーマットする方法は?

分類Dev

ドメインイベントを使用してデータベース内のエンティティを更新する

分類Dev

オンプレミスのデータゲートウェイトラフィックをサイト間VPN経由でルーティングする方法

分類Dev

.netドライバーを使用してcassandraデータベースからエンティティの列を無視する方法はありますか?

分類Dev

エラスティックプールを備えたエンティティフレームワーク。SaaSクライアントデータベースを管理する方法は?

Related 関連記事

  1. 1

    インラインエディタを使用してDialogflowフルフィルメントでhttpリクエストをテストする方法

  2. 2

    ラムダ式とlinqを使用して、EFを使用して別のエンティティモデルタイプのリストを含むエンティティモデルをデータベースに追加する方法

  3. 3

    ウィンドウフォームのボタンクリックイベントを使用して、データテーブルに存在する行の総数を単一のラベルに取得する方法c#

  4. 4

    GCPデータストアエンティティデータをcsvファイルにエクスポートする方法を探しています

  5. 5

    アクティビティとフラグメント間のインターフェイスを使用して双方向にデータを送信する方法

  6. 6

    データベースエンティティのインターフェイスとしてトレイトを使用する

  7. 7

    ライフサイクルイベントをアクティブに正しく監視する方法

  8. 8

    JPA2を使用してユーザータイプのフィールドを含むエンティティを永続化する方法

  9. 9

    エンティティフレームワークを使用してデータベース内のレコードを更新するときにモデル検証をオーバーライドする方法

  10. 10

    c#.netsdkを使用してデータファクトリパイプラインでkustoアクティビティを作成する方法

  11. 11

    Bokeh:2つのインタラクティブウィジェットを使用してCustomJSでデータセットをフィルタリングする

  12. 12

    JupyterLabを使用してインタラクティブなフィギュアをループで更新する方法

  13. 13

    一連のクラスをjarライブラリからjpaエンティティにマップしてデータベーステーブルを作成する方法

  14. 14

    curlwgetを使用してインタラクティブなhttpサイトからLinuxシェルにファイルをダウンロードする

  15. 15

    インターフェイスリスナーを使用してアクティビティからフラグメントにデータを送信する

  16. 16

    ReactでsetStateを使用してオブジェクトを更新する(ソリディティイベントフィルター)

  17. 17

    TeamFoundationクライアントを使用してビルドアーティファクトから個々のファイルを取得する方法

  18. 18

    データベースを使用したオフラインツールのベストプラクティス

  19. 19

    タイマーティックイベントを取得して別の関数C ++ / CLIを中断する方法

  20. 20

    インターフェイスを使用してアクティビティからフラグメントにコールバックを戻す方法

  21. 21

    コマンドラインを介してEclipseでアクティブなエディターのファイルパスを取得します

  22. 22

    クリティカルイベントとエラーイベントをCSVファイルにフィルターする

  23. 23

    JPAネイティブクエリを使用してポイントタイプデータを更新するにはどうすればよいですか?

  24. 24

    JPAエンティティをデータベース列を使用してJSONとしてフォーマットする方法は?

  25. 25

    JPAエンティティをデータベース列を使用してJSONとしてフォーマットする方法は?

  26. 26

    ドメインイベントを使用してデータベース内のエンティティを更新する

  27. 27

    オンプレミスのデータゲートウェイトラフィックをサイト間VPN経由でルーティングする方法

  28. 28

    .netドライバーを使用してcassandraデータベースからエンティティの列を無視する方法はありますか?

  29. 29

    エラスティックプールを備えたエンティティフレームワーク。SaaSクライアントデータベースを管理する方法は?

ホットタグ

アーカイブ