4

デフォルトの TopLink 永続マネージャを使用して、Glassfish で EJB3 を使用しています。セッション Bean 内で、持続性マネージャーが DB 例外をキャッチすると、トランザクションをロールバックするようにマークし、EJBException をスローしてから、RollbackException をラップします。ここで、これらの例外のいずれかの例外によって引き起こされた元の jdbc 例外を取得できると期待していましたが、そうではありません。

問題の内容をユーザーに報告する必要があるため、元の例外を取得することが重要です。これを行うには、SQL エラー コードを分析する必要があります。

Toplink からこの情報を取得できるかどうかは誰にもわかりませんか? または、Hibernate がそれを可能にするかどうか?

ありがとう、

4

4 に答える 4

3

同じ問題がありました。最終的にAroundInvokeインターセプターメソッドを使用しました。これにより、サーバー側で例外をキャッチし、必要な情報を抽出してラップして独自の例外をスローし、EjbContextを設定してトランザクションをロールバックできます。

うまくいかない場合は、例を示します。

于 2009-10-05T06:53:17.370 に答える
1

同じ質問があります:JPAから生成されたSQLエラーメッセージを取得するにはどうすればよいですか?

解決策も見つかりませんでしたが、この行をpersistence.xmlに追加しました

    <properties>
        <property name="toplink.logging.level" value="FINE" />
    </properties>

そして今、発行されたSQLコマンドを見ることができます。

参考: http ://www.jairrillo.com/blog/2008/09/04/introduction-to-jpa-part-1-getting-started/

于 2009-10-27T04:12:40.470 に答える
1

良い質問だ、アリ

データベース例外をスローしたいのはわかっていますが、例外が発生した場合、ほとんどの場合、アプリケーションは初期状態を復元できないか、回復方法を知りません。そのため、実行時例外として処理する必要があります。データベース例外のいくつかの問題には、

  • データベース接続の失敗
  • クエリが間違っています
  • テーブルまたは列が存在しません

上記のように、アプリケーションは初期状態を復元できません。初期状態を復元できると思われる場合は、アプリケーション例外を使用する必要があります。クライアントは、ビジネス メソッドによってスローされたのと同じアプリケーション例外を受け取ります。ビジネス メソッドによってスローされた正確な例外を取得できるようにする場合は、次の 2 つの選択肢があります。

  • ビジネス デリゲート パターンを使用して EJB にアクセスする

ご存じのように、実行時例外は EJBException によってラップされるため、次のようなものを使用する必要があります。

このステートレス セッション Bean があるとします。

@Stateless
public class BeanImpl implements Bean {

    public void doSomething() {

        try {
            // some code
        } catch(SomeException e) {
            throw new EJBException(e);
        }

    }        

}

したがって、ビジネス デリゲートを介してセッション Bean をラップします。

public class BeamBusinessDelegate implements Bean {

    // your stateless session bean goes here
    private Bean bean;

    public BeamImpl() {
        InitialContext i = new InitialContext();

        bean = (Bean) i.lookup(<GLOBAL_JNDI_ADDRESS_OR_RELATIVE_ENVIRONMENT_NAMING_CONTEXT_ADDRESS>);
    }

    public void doSomething() {
        try {
            bean.doSomething()
        } catch(EJBException e) {
            throw e.getCause();
        }
    }
}

または、必要に応じて EJBException を拡張できます

public class DatabaseException extends EJBException {

}

だからあなたのビジネス方法で

@Stateless
public class BeanImpl implements Bean {

    public void doSomething() {

        try {
            // some code
        } catch(SomeException e) {
            throw new DatabaseException();
        }

    }        

}

よろしく、

于 2009-10-03T18:22:02.750 に答える
1

私がやりたいことをするために私が見つけた唯一の方法は、manager.flush() を使用してマネージャーに db への書き込みを強制し、それがスローする PersistenceException をキャッチすることです。その後、必要に応じてデータベース エラーをログに記録し、EJBException をスローして強制的にロールバックすることができます。フラッシュを実行するためにコンテナーをそのままにしておくと、TopLink に関する有用なメッセージが取り返しのつかないほど失われるようです。

于 2009-10-13T09:28:54.910 に答える