SpringBoot のようなフレームワークで非常に多くのことができるのは素晴らしいことです。
必要なのは JPA エンティティ クラスと単純なリポジトリ インターフェイスだけであり、SpringData は一般的な CRUD データベース操作に必要なものをすべて提供します。
単純な REST コントローラー クラスを作成し、REST API を実行していますよね?
やあ、でも DTO を書くのを忘れていました!しかし、アプリがなくても機能するのに、実際にはなぜそれが必要なのでしょうか?
確かに一般的な理由がいくつかあります:
しかし、他にも奇妙なことが起こる可能性があります。私の経験に基づいて、奇妙な例を 1 つ紹介します。
この GitHub リポジトリには、DTO なしで動作するシンプルなアプリケーションが含まれています。ユーザー エンティティがあり、各ユーザーは複数のトランザクションを持つことができます。リポジトリと RestController の間に Service Bean もあり、データベース アクセスの例外をキャッチします。
実稼働対応のアプリケーションを作成したいので、Hibernate に DDL を生成させたくありません。代わりに、テーブルを作成する schema.sql があります (後で Flyway または Liquibase に切り替える可能性があります)。この簡単な例では、テーブルが空にならないように data.sql も用意しています。
アプリケーションを実行し、http://localhost:8080/users で API エンドポイントを呼び出すと、ユーザーとそのトランザクションを含む予想される JSON が取得されます。
次に、Transaction クラスの //!!
とマークされた 2 行のコードに注目してみましょう。
@JsonIgnore //!!
最初の特徴は、Transaction クラスで @JsonIgnore アノテーションを User 参照に追加する必要があることです。このアノテーションがないと、JSON シリアル化は無限再帰によりクラッシュします。
次に、誰かがトランザクション エンティティに別のフィールド (説明) を追加するという間違いを犯したが、SQL ステートメントの調整を忘れた (または、スキーマ変更が適用されていない環境に対してアプリケーションを実行した) と想像してみましょう。
プライベート文字列の説明;//!!
もちろん、今度は API 呼び出しは失敗します。しかし、エラー処理を見てください。 UserService 内の catch 句が期待どおりに機能しません。代わりに、ログに奇妙なスタック トレースが表示されます:
GlobalExceptionHandler : 予期しないエラー org.springframework.http.converter.HttpMessageNotWritableException: JSON を書き込めませんでした:
私はかつてこの状況を見たことがあり (明らかに、この例よりもはるかに大規模なアプリケーションでした)、なぜ SQL 例外がサービスをエスケープし、なぜ HttpMessageNotWritableException が発生するのかを理解するのにかなりの時間がかかりました。見えますか?
何が起こるかというと、UserService クラスは (UserRepository 経由で) USERS データベース テーブルのみをクエリします。デフォルトの Hibernate 遅延ロードのため、トランザクション エンティティは結果の一部ではありません。 Jackson デシリアライザーが User インスタンスから JSON を作成しようとする場合にのみ、Hibernate にトランザクション エンティティをフェッチさせる getTransactions メソッドを呼び出します。
これが、JSON と SQL を組み合わせた奇妙なスタックトレースが得られる理由です。この例外は、それをどう処理すればよいかわからない GlobalExceptionHandler によってキャッチされます。これが、ログ メッセージが「予期しないエラー」となる理由です。
この小さな演習で、アプリケーションの異なるレイヤーを混在させることがいかに危険であるかをより深く理解していただければ幸いです。アプリケーションがまだ小さいうちに、アプリケーションの「晴れた日」のシナリオだけを見ると、一部の開発者は手遅れになるまで間違った行為を続ける可能性があります。
DTO とアプリケーションの他の層の間でフィールドをマッピングする定型コードを記述する必要はありません。 MapStruct が代わりにそれを実行します。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3