2017-11-17 2 views
0

私はエンティティコール会社、もう1人のエンティティコールトークンを持っています。休止状態での汚れチェックの回避方法

1会社には多くのトークンがあります。

だから私の会社の実体に、私は次のようなものがあります:

@OneToMany(mappedBy = "companyId") 
public Set<Token> getTokens() { 
    return tokens; 
} 

しかし、私はそれは、復帰前にフォローのようなその何かをトークンのリストを変更し、復帰時にいくつかのロジックを持っています。

@OneToMany(mappedBy = "companyId") 
public Set<Token> getTokens() { 
    tokens.remove(token); 
    return tokens; 
} 

私はトークンリストの値を変更するので、hibernateを使用してdbから会社オブジェクトを選択するたびに、会社テーブルが自動的に更新されます。

私が理解している限り、これは休止状態の汚れチェックの動作です。だから、Hibernateが何か変わったことを検出すると、データベースへの更新を行います。

これを回避できる方法はありますか?たとえば、単にhibernate関数を呼び出すだけで、hibernateはトークンリストが汚れていることを知り、更新を行いません。

はい、getTokens()のフィルタリングロジックは適切ではありません。右のフィルタリングロジックはエンティティレベルでは適用されません。しかし、現在、この方法を使用する場所が多いため、このエンティティレベルで変更すると、他の場所に影響を与えます。また、他の場所を変更した場合は、再度アプリケーション全体を再テストする必要があります。

このように私はこれについてより良い方法を見つけようとしています。

+1

元のデータのコピーを作成し、コピーされたデータであなたのロジックを実行して、コピーしたデータを返す:
はたぶん実装下記のに役立ちます。 –

答えて

1

あなたが実際に望むのは、Hibernateが自動flushingから防ぐことです。

hibernate docsを参照してください:

フラッシングは、メモリに保存されている持続可能な状態で基盤となる永続 ストアを同期するプロセスです。

この問題を解決するには、FlushMode.MANUALを設定することにより、取扱説明書を自動からFlushModeのデフォルト設定を変更することです。このようにして、汚れたチェック機構は前述の同期を停止させる。

hibernate documentationに記載されているように、Session.flush()がアプリケーションによって明示的に呼び出されたときには、Sessionは常にフラッシュされます。

は、ここでそれはあなたが明示的にフラッシュの価格を支払う必要が提案された解決策に従うならば、あなたが明示的に 呼び出しSession.flush()方法は、データベースに何かをコミットするたびに必要があることを意味していることに言及しなければなりません。

hereFlushModeに関するいくつかの有用な資料は、休止状態の文書で正式に文書化されています。

UPDATE
このソリューションでは、セッションに適用されますので、あなたが唯一の特定のエンティティにこれを適用したい場合は、2つのメソッドを作成してみてください。1つはMANUALに設定し、もう1つはデフォルトのAUTOに戻すためのものです。この方法では、手動設定後に値を変更してフラッシュを防ぐことができます。その後、他のエンティティに影響を与えないようにデフォルトに戻します。 、あなたが行うことができる一つの代替ではなく、元のデータを変更するのである

@Autowired 
private SessionFactory sessionFactory; 


@OneToMany(mappedBy = "companyId") 
public Set<Token> getTokens() { 
    setFlushModeManual(); 
    tokens.remove(token); 
    setFlushModeAuto(); 
    return tokens; 
} 

private void setFlushModeManual() { 
    sessionFactory.getCurrentSession().setFlushMode(FlushMode.MANUAL); 
} 

private void setFlushModeAuto() { 
    sessionFactory.getCurrentSession().setFlushMode(FlushMode.AUTO); 
} 
+0

私はセッションを明示的に呼び出す必要があります。実際には、このモジュールでは休止状態のチェックを避けたいだけですが、他のモジュールではチェックしません。私はこの会社でのみ適用する方法を見つけることを試みています.getTokens()、可能かどうかはわかりません。 –

+0

回避策を使用して回答を更新しました。これを試して、これが役立つかどうかを確認してください。 –

+0

こんにちは@Anastasios、申し訳ありませんがまだそれについて本当に理解していない。 'setFlushModeManual()'と 'setFlushModeAuto()'メソッドは、どのように動作するのですか?私は、任意の用語や変数に 'FlushMode'を代入していませんでしたが、プログラムはgetTokensの部分がManualかAutoになるのをどのように理解していますか?私は冬眠するのがとても新しいです。 –