あなたがJava開発者であり、次の大きなプロジェクトを開始しようとしていると想像してみてください。あなたはプロジェクトの残りの間あなたに固執するであろう基本的な決定をする必要があります。プレーンSQLを扱いたくないので、柔軟なデータモデルの最適なオブジェクト指向の抽象化を選択する必要があります。あらゆる種類のデータをサポートし、理想的にはあらゆる種類のデータベースをサポートする必要があります。
明白な答えはただ使うことです Hibernate 、 正しい? Java開発者の90%があなたに同意しますが、それは正しい決定になりますか?
やみくもに使用すると何がうまくいかないか見てみましょう Hibernate それが受け入れられた標準だからです。
Java開発者のMonicaについて考えてみましょう。モニカは最近建築家の役割に昇進し、現在は彼女の会社で新製品のテクノロジースタックのレイアウトを担当しています。彼女は、Javaの世界では、データベース通信を処理するための優れたツールが1つしかないことを知っています。 Hibernate 。 Hibernate よく知られていてサポートされています JPA規格 。ただし、プロジェクトを開始する前に、いくつかのことを確認することをお勧めします。幸いなことに、彼女の同僚であるベンは、適切な人を知っています。
ベン -こんにちはモニカ、ジョンを紹介したいと思います。彼は Hibernate 専門家、そして彼はあなたを助けるつもりです。
モニカ -ねえジョン、あなたが私のために時間を見つけてくれてうれしい。ですから、私たちは次の大きなものを構築しています。次のFacebookやGoogleになることを計画しています。忙しい日。それは巨大になるでしょう。本当に素敵!みんなとても興奮しています!私は建築家の役割に昇進したので、使用するスタックを選択する必要があります。唯一欠けている部分は永続性です…
ジョン - Hibernate !
モニカ - はい!丁度!まさに私が考えていたものです!それは完全に一致し、私たちにとって本物のようです。市場で証明され、長い歴史を持つ、真のエンタープライズ問題に対する真のエンタープライズソリューション。たくさんの前向きな経験を聞いたことがあります。ただし、チームメートの1人に問題があります。彼は完全に反対している。彼はデータベースについて多くのことを知っており、アプリケーションとデータベースの間に別のレイヤーを追加することを恐れています。彼はとても頭がいいので、これが良い決断だと彼に納得させるには、本当に良い議論が必要です。それを手伝ってくれませんか。
ジョン - もちろん!よろしくお願いします。 Hibernate 確かに、優れたツールです。銀行などの大規模で真のエンタープライズソリューションで広く使用されています。間違いはありません。永続性を考える:ピック Hibernate 。 Javaで書いている場合、これは絶対に正しい選択であり、さらに他の言語用のポートがあります。必要な職務記述書の数をご覧ください。
モニカ -絶対に同意します!私も同じ気持ちです。以前のプロジェクトでは、ほとんどが古いJDBCを介したSQLを使用していました。ばかげている!知っている!しかし、ここに問題があります。チームには本当に賢いSQL担当者がいて、SQLが Hibernate 彼らは緊張しました。それは醜くて読めないようでした。これは将来問題になるのでしょうか?
ジョン -見てください。 DBAの人たちは別の見方をしています。彼らは恐れています Hibernate それはプロジェクトにおける彼らの役割に取って代わるように思われるからです。さらに、データベースにはクエリオプティマイザが組み込まれているため、これらのクエリが実際にどのように表示されるかを心配する必要はありません。データベースはあなたのためにそれを最適化します。 SQLでは不可能な迅速な開発がすべてです。
モニカ - 本当に?! SQLを扱っていませんか?すごい!前回、DBAがいくつかのクエリを最適化するために数週間を費やしました。数週間!ああ、これを言うのはとても恥ずかしいと思いますが、私たちが…ストアドプロシージャを使用していることを知っていました(笑)。ああ、それはそのような混乱でした。プロジェクトがまだそれを使用していると信じられますか?私はそこにいる人々をとても気の毒に思います。彼らはまだこの退屈なコードを何度も何度も書かなければなりません。それはまだJavaまたはSQLプロジェクトなのだろうか?
ジョン -それはまさにオブジェクト指向アプローチとリレーショナルアプローチの違いです。これは、いわゆるオブジェクト指向のインピーダンス不整合です。 Hibernate このギャップを埋めることができます。開発者は、ビジネスロジックの構築に集中できます。プッシュ機能は、利害関係者と経営陣全体を幸せにします。最も重要なことをしなさい:ビジネス!多くの定型コードが消え、ロジックとデータの間に魔法のような目に見えないが信頼できる接続ができます。
モニカ - 相互協力。完全な相乗効果。データベースのように、最初から言語の一部でした。この技術的な信仰の飛躍のリーダーになれたことをとてもうれしく思います。これは、ソフトウェアトレッキングのワープ速度のようなものです。
ジョン -うん!あなたはそれを持っています!
モニカ -おやおや、とても興奮しています!ありがとう、ジョン!準備できました!
Hibernateは特効薬ではありません。デフォルトのデータベースソリューションとして扱わないでください。 つぶやきモニカ -ジョンさん、昨年お話ししたプロジェクトを覚えていますか?
ジョン - 承知しました。調子はどう?
モニカ -まもなく生産を開始します。すべて問題ありませんが、いくつかの質問が出てきました。
ジョン -確かに、私を殴ってください。
モニカ -まあ、データベーススキーマを最初から生成することはできなくなりました。データを失うことなくスキーマの変更をサポートするための最良の方法は何ですか?
ジョン -まあ、まず、 Hibernate 本番移行ツールとして使用するためのものではありません。 FlywayDBやLiquibaseのようなものを使用してください。とても簡単です。移行スクリプトを書き留めてから、エンティティモデルを更新します。 Hibernate マッピングなので、実際のデータベース構造と同期し続けます。
モニカ -うーん、なるほど。前のプロジェクトでは、単純なSQL移行を使用していました。
ジョン -それも結構です。エンティティモデルとスキーマの同期を維持している限り、好きなように実行してください。
モニカ - そうですか。別のことがあります。私たちは常に怠惰な/熱心なフェッチの問題に苦しんでいます。ある時点で、すべてを熱心にやろうと決心しましたが、それは最適ではないようです。また、セッションがないなどの理由で、一部のフィールドにアクセスできない場合もあります。それは正常ですか?
ジョン -あなたはについてもっと学ぶ必要があります Hibernate 。データベースからのマッピングは簡単ではありません。基本的に、それを行うには複数の方法があります。あなたはただあなたのために働く方法を選ぶ必要があります。遅延フェッチを使用すると、これらのオブジェクトをオンデマンドで読み込むことができますが、アクティブなセッション内で操作する必要があります。
モニカ -最終的な展開に使用するデータベースエンジンについては、まだ苦労しています。私は思った Hibernate 移植性はありましたが、MS SQLの魔法を使用するネイティブクエリがいくつかあり、実際には本番環境でMySQLを使用したいと考えています。
ジョン - Hibernate 分離基準またはHQLを使用している限り、柔軟性が得られます。ネイティブクエリは、ソリューションをデータベースにバインドするだけです。
モニカ -その場合、MSSQLに固執する必要があるようです。最後の質問:私のチームメートは、HQLには「制限」キーワードはないと言いました。彼は冗談を言っていると思いましたが、私もそれを見つけることができませんでした。愚かな質問でごめんなさい…
ジョン -確かに、HQLには「limit」キーワードはありません。これはデータベースベンダー固有であるため、クエリオブジェクトを介して制御できます。
モニカ -他のすべての要素がHQLにあるのは奇妙に思えます。気にしないで。御時間ありがとうございます!
関連: マルチテナントアプリケーションを構築する方法:Hibernateチュートリアルモニカ -ジョン、最初はSQLを扱うつもりはありませんでしたが、今はそうしなければならないようです。私たちのニーズは高まっており、それを回避する方法はないようです。気分が悪いのですが、SQLを日常的に使い始めました。
ジョン -まあ、それは間違いではありません。最初はデータベースに集中する必要はありませんでした。ただし、プロジェクトが大きくなるにつれて、SQLを使用してパフォーマンスの最適化に取り組むことをお勧めします。
モニカ -エラーを探すのに何日も費やすことがあります。分析しなければならないようです Hibernate -SQLが期待どおりに機能せず、予期しない結果が生じる理由がわからないため、SQLが生成されました。でよく知られているいくつかの問題にぶつかりました Hibernate バグトラッカー。さらに、エンティティモデルの同期を維持しながら、適切な移行を作成することは困難です。について多くのことを学ぶ必要があるため、時間がかかります Hibernate 内部とそれがどのように機能するかを予測します。
ジョン -常に学習曲線があります。たくさん書く必要はありませんが、それがどのように機能するかを知る必要があります。
モニカ -より大きなデータセットでの作業も面倒です。最近、データベースに大量のインポートを実行しましたが、非常に遅くなりました。その後、セッションを高速化するには、セッションをクリアする必要があることがわかりました。それでも、それでもかなり遅いので、プレーンSQLステートメントとして書き直すことにしました。面白いのは、プレーンSQLを書くことが実際にそれを行う最も速い方法だったので、最後のオプションとしてそれを行うことにしました。
ジョン -インポートはオブジェクト指向のプロセスではありません。 Hibernate オブジェクト指向設計に焦点を当てています。ネイティブクエリはいつでも使用できることを忘れないでください。
モニカ -方法を理解するのを手伝ってくれませんか Hibernate キャッシュは機能しますか?わからない。いくつかの第1 /第2レベルのキャッシュがあります。これはどういうことですか?
ジョン - 承知しました。これは、永続データのいわゆるトランザクションレベルのキャッシュです。クラスごとおよびコレクションごとに、クラスターまたはJVMレベルのキャッシュを構成することができます。クラスター化されたキャッシュをプラグインすることもできます。ただし、キャッシュは、別のアプリケーションによって永続ストアに加えられた変更を認識しないことに注意してください。ただし、期限切れのキャッシュデータを定期的に削除するように構成できます。
モニカ -申し訳ありませんが、私は悪い日を過ごしていると思います。これについてもう少し説明していただけますか?
ジョン - 承知しました。オブジェクトをsave
、update
、saveOrUpdate
に渡すか、load
、get
、list
、| _ + _を介してオブジェクトを取得するときはいつでも|またはiterate
の場合、そのオブジェクトはセッションの内部キャッシュに追加されます。オブジェクトとそのコレクションを第1レベルのキャッシュから削除することもできます。
モニカ -…
ジョン -さらに、キャッシュモードを制御できます。 scroll
を使用できますアイテムを第2レベルのキャッシュに読み書きするモード。 normal
を使用する2番目のレベルから読み取るモードですが、書き戻すことはできません。 get
と同じput
を使用しますしかし、あなたは第二レベルから読むことはできません。 get
も使用できますモード。これは第2レベルに書き込みますが、そこから読み取らず、refresh
をバイパスします。プロパティ。データベースから読み取られたすべてのアイテムについて、第2レベルのキャッシュを強制的に更新します。
モニカ - そうですか。 OK。これについて考えさせてください。ああ、遅いです、私は行かなければなりません。御時間ありがとうございます!
ジョン - どういたしまして!
モニカ -ジョン、私たちはソフトウェア開発の新時代に入っていると思いました。私たちは光年のジャンプをしていると思いました。しかし、4年経った今でも、同じ問題を別の角度からしか扱っていないようです。私は学ばなければなりませんでした Hibernate アーキテクチャ、構成、ロギング、命名戦略、タプリザー、エンティティ名リゾルバー、拡張識別子ジェネレーター、識別子ジェネレーターの最適化、ユニオンサブクラス、XDocletマークアップ、インデックス付きコレクションとの双方向アソシエーション、3値アソシエーション、idbag、暗黙のポリモーフィズムと他の継承マッピングの混合、複製2つの異なるデータストア間のオブジェクト、デタッチされたオブジェクトと自動バージョン管理、接続解放モード、ステートレスセッションインターフェイス、コレクションの永続性の分類、キャッシュレベル、レイジーまたはイーガーフェッチなど。私が知っていることすべてをもってしても、私たちはひどく失敗したようです。それはソフトウェアの大失敗です!究極の失敗!災害!ハルマゲドン!
プロジェクト分析で最も重要なステップは次のとおりです。
ジョン - 待つ!何が起こった?
モニカ -行き止まりになりました。私たちのアプリケーションのパフォーマンスは途方もなく遅いです!レポートを受け取るには、2日待たなければなりません!顧客のダッシュボードを実際に生成するのに2日。これは、ダッシュボードがますます時代遅れになる一方で、毎日計算テールを増やす必要があることを意味します。私たちのDBAエキスパートは、いくつかのクエリを最適化するために2か月間取り組んできましたが、データベース構造は完全に混乱しています。彼をサポートしている開発者がいますが、問題はDBAがSQLで考えていることであり、開発者はこれを分離された基準またはHQL形式に変換しようと何日も費やしています。現時点ではパフォーマンスが重要であるため、可能な限りネイティブSQLを使用するようにしています。とにかく、データベーススキーマが間違っているように見えるため、多くのことを行うことはできません。オブジェクト指向の観点からは正しいと感じましたが、リレーショナルの観点からはばかげているようです。私は自分自身に問いかけています:これはどのように起こったのですか?開発者は、エンティティ構造の変更は多大な労力を要すると言っているので、それを買う余裕はありません。前回のプロジェクトではめちゃくちゃだったのを覚えていますが、こんなに重要なポイントにたどり着くことはありませんでした。データを処理するために、まったく異なるアプリケーションを作成することができました。エンティティモデルが常に適切に動作することを確認するのは非常に難しいため、生成されたテーブルを変更するのは危険です。そして、これは最悪の部分でもありません!パフォーマンスを向上させるには、データベースの問題だけでなく、データベースとアプリケーションの間のレイヤー全体の問題も解決する必要があります。圧倒的です!私たちはこれらの新しい人を持っています、あなたが知っている、コンサルタント。彼らはデータを抽出し、それを他のストレージに入れて、外部から計算を実行しようとしています。時間がかかりすぎます!
ジョン -何と言ったらいいのかわからない。
モニカ -ジョンが見えます。私はあなたを責めたくありません。私が選んだ Hibernate これらすべての問題を解決するためですが、今ではそれが特効薬ではないことを学びました。損傷が発生し、元に戻せません。実は、何かお聞きしたいのですが、私はキャリアの最後の4年間を Hibernate もの。現在の会社には未来がないようです。手伝って頂けますか?
ジョン -ねえ、ピーター、モニカを紹介させてください。
ピーター -ねえ、モニカ!私たちはあなたが知っている新しい次の大きなものを構築しています。巨大になりそうです! Uberのようになりたい!多分どれだけ持続性があるか知っていますか…
モニカ - Hibernate !
モニカは Hibernate 専門家 。しかしながら、 Hibernate この場合、間違った決定でした。彼女の解決策が元の問題よりも大きな問題になったことを彼女が発見した瞬間、それはプロジェクト全体にとって最大の脅威でした。
データはアプリケーションの中心的な目的であり、好むと好まざるとにかかわらず、アーキテクチャ全体に影響を与えます。話から学んだように、 ない 使用する Hibernate Javaアプリケーションがデータベースを使用しているという理由だけで、または 社会的証明 。柔軟性を取り入れたソリューションを選択してください。堅牢なJDBCラッパーには、次のような多くのオプションがあります。 JdbcTemplate または 流暢なJDBCラッパー 。あるいは、他の強力なソリューションがあります。 jOOQ 。