0

Webアプリでは、エンティティを「ソフト削除」するためにHibernateの@SQLDeleteアノテーションを使用します(つまり、ステータス列を、実際にテーブルから削除するのではなく、「削除済み」ステータスを示す値に設定します)。

エンティティコードは次のようになります。

@Entity
@SQLDelete(sql="update pizza set status = 2 where id = ?")
public class Pizza { ... }

さて、私の問題は、Webアプリケーションが、テーブルが属するスキーマの所有者を使用してDBに接続しないことです。たとえば、スキーマ(Oracleの場合)はと呼ばれpizza、Webアプリケーションが接続に使用するdbユーザーはですpizza_webapp。これはセキュリティ上の理由によるものです。ユーザーにはpizza_webapp選択/更新/削除権限のみがあり、DB自体の構造を変更することはできません。ここでは選択の余地はありません。変更できないポリシーです。

テーブルが実際に存在するスキーマの名前を、hibernate-default_schemahibernateconfigのパラメーターで指定します。

<property name="hibernate.default_schema">pizza</property>

これは、マップされたエンティティを通過するすべてのものに対して正常に機能します。Hibernateは、生成するSQLのテーブル名の前にスキーマ名を追加する方法を知っています。ただし、生のSQLではなく、生のSQLが@SQLDelete含まれています。これは「そのまま」実行され、結果として"table or view not found error"

これまでのところ、pizza_webappスキーマを指す同義語をスキーマに追加することで、この問題を回避しましたpizza。それは機能しますが、エンティティが追加されたときに複数のDB間で維持するのは楽しいことではありません。

それで、パラメータを考慮に入れることは可能@SQLDeleteですhibernate.default_schemaか?

(注:明らかに、SQLでもスキーマ名をハードコーディングしたくありません...)

4

2 に答える 2

1

はい、可能です:

@SQLDelete(sql="update {h-schema}pizza set status = 2 where id = ?")
于 2019-10-08T15:16:49.443 に答える
0

この問題に対するHibernateソリューションは見つかりませんでした。ただし、Oracleの機能に基づく回避策を見つけました。私はそれを使用する前に私のセッションにこれを行います:

//set the default schema at DB session level for raw SQL queries (see @SQLDelete)
HibernateUtil.currentSession().doWork(new Work() {
    @Override
    public void execute(Connection connection) throws SQLException {
        connection.createStatement().execute("ALTER SESSION SET CURRENT_SCHEMA="+HibernateUtil.getDefaultSchema());
    }
});

私は問題なく動作しますが、残念ながらOracleでのみ機能します(少なくとも今のところは問題ありません)。たぶん、他のRDBMSでも同じことを達成するためのさまざまな方法がありますか?

編集:getDefaultSchema()私のクラスのメソッドは、HibernateUtilHibernateの設定からデフォルトのスキーマを取得するためにこれを行います:

defaultSchema = config.getProperty("hibernate.default_schema");

config私のorg.hibernate.cfg.Configurationオブジェクトはどこにありますか。

于 2012-11-22T11:25:00.350 に答える