2009-05-23 9 views
25

私がHibernateを使用する主な理由の1つは、コードを書き直すことなく別のデータベースに切り替える柔軟性を提供することです。休止状態のエンティティでデータベースビューを扱う優雅な方法?

これまで、私は休止状態のエンティティが一致するテーブルに追加のビューを定義する良い方法を理解していませんでした。私はまだ単純なSQLスクリプトを使っています。休止状態で管理されるテーブルのビューを定義するよりエレガントな方法はありますか?

理想的には、私はSQLスクリプトが他の種類のデータベースと互換性がないことを心配する必要がないように、HQLまたは別の汎用メソッドを使用したいと思います。

これを行う方法がある場合、2番目の問題は、これらのビューから「合成」読み取り専用インスタンスを取得することです。これにより、集約されたデータをUIに簡単に供給できるようになります。

EDIT:

それは私が十分に問題を明確にしていないかのように思えるので、ここで私が何をしようとしています何:私は、使用するデータベースから独立したコードを書きたいです。私は休止状態を使用しているので、私は方言構成ファイルを変更するだけで、別のDBMSを使用することができます。

質問:どのように特定のSQL方言に頼るせずに私の休止状態のエンティティビューを作成するために、あるいはHQL(すべてのポータブルを保つために)?それが可能であれば、HQLを使用してこれらのビューをクエリすることができます。つまり、読み取り専用の集約エンティティを作成することはできますか?そこに私を助けるための追加の休止状態のプラグインがありますか?今まで何も見つかりませんでした: -/

答えて

22

各方言は、基礎となるデータベースのデータ定義言語(DDL)の限られたサブセットをサポートしてHibernateは自動的に、あなたのためのビューを作成しません。基本的には、動作中のスキーマを生成するのに十分なDDLをサポートしますが、ビューなどの「余分な」オブジェクトの作成を処理するには十分ではありません。

しかし、すべてが失われません。 Hibernateは、XMLマッピングファイル内に追加のデータベースオブジェクトを作成(およびドロップ)する機能を提供します。これらのオブジェクトは特定の方言にスコープすることができます。例えば、私はこのようなマッピングを持つことができます:

<hibernate-mapping> 
    <class name='com.mycompany.myproduct.Customer' table='tbl_customer'> 
    <id name='id' column='customer_id'> 
     <generator class='native'/> 
    </id> 
    <property name='name' length='50' unique='true' not-null='true' /> 
    </class> 

    <database-object> 
    <create>create or replace view read_only_cust...</create> 
    <drop>drop view read_only_cust</drop> 
    <dialect-scope name='org.hibernate.dialect.Oracle9Dialect' /> 
    </database-object> 
</hibernate-mapping> 

あなたがより多くの「データベース・オブジェクト」セクションを追加することによって、あなたが望むものは何でも、追加のビューを作成することは自由です。サポートしたいデータベースごとにSQL(DDL)を書く必要がありますが、それらは方言にスコープされているため、Hibernateはスキーマのエクスポート時に選択された方言に対してのみSQLを実行します。

+1

ありがとう!これは唯一の方法です。 SQLスクリプトが周りに横たわっているよりも良い:...-) –

0

ビューをデータベース内に直接宣言できますか? 次に、ビューから直接選択することができます。 chapter 10.4.4 of the Hibernate manual

これは、データベースビューから選択し、Hibernateに自動的にデータをエンティティに含めるようにする必要があります。

もちろん、ビューにはパラメータはありません。 Hibernate 3はストアドプロシージャをサポートするはずですが、私はこれを使用しました。

+0

感謝を。ここで少し誤解があります(私は質問を編集してより明示的にします):Hibernateエンティティを取得するためにSQLを使用するのではなく、SQLを使用せずにHibernateエンティティに対してビュー*を宣言する方法(これは使用されるDBシステムに依存し、したがってDBMSに依存しないIMHOの基本的なiddeaと矛盾する)。 –

0

「ビューの作成」とはどういう意味ですか?私はそれが純粋なDBコンテキストから何を意味するかを知っていますが、それはあなたが意味するものではありません - そうですか?

新しいJavaクラスを同じテーブルにマップして「ビュー」を作成することも、HQLを使用して他の永続クラスによってマップされたサブセットを選択することもできます。

HTH

12

は同じ問題を抱えていたと休止doucmentationで次の解決策を見つけた:

休止 マッピングするための図で とベーステーブルとの間の違いはありません。 データベースレベルでは透過的ですが、一部のDBMSでは が正しくビューをサポートしていませんが、特に 更新があります。 ビューを使用したい場合は、 をデータベースに作成することはできません(つまり、従来の スキーマを使用)。この場合、あなたは 不変をマッピングすることができますし、読み取り専用のエンティティを 与えられたSQLの副選択式に:あなたの答えのための

<class name="Summary"> 
    <subselect> 
     select item.name, max(bid.amount), count(*) 
     from item 
     join bid on bid.item_id = item.id 
     group by item.name 
    </subselect> 
    <synchronize table="item"/> 
    <synchronize table="bid"/> 
    <id name="name"/> 
    ... 
</class> 

https://docs.jboss.org/hibernate/stable/core/manual/en-US/html_single/#mapping-declaration