1. ホーム
  2. java

[解決済み] 複数のメソッド引数で @Cacheable キー

2023-04-23 18:35:08

質問

からの springドキュメント :

@Cacheable(value="bookCache", key="isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

どのようにすれば @Cachable を使うには isbncheckWarehouse をキーとするか?

どのように解決するのですか?

更新 : 現在のSpringキャッシュの実装では、特に指定がない場合、すべてのメソッドパラメータをキャッシュキーとして使用します。もし、選択されたキーを使いたい場合は Arjanの回答 では、SpELリスト {#isbn, #includeUsed} これはユニークキーを作成するための最も簡単な方法です。

から Springのドキュメント

デフォルトのキー生成方法は、Spring 4.0. 以前のバージョンのSpringでは、複数のキーパラメータに対して、equals()ではなく、パラメータのhashCode()のみを考慮するキー生成ストラテジーを使用していました。 のみを考慮し、equals() は考慮しません。 の衝突を引き起こす可能性がありました (背景は SPR-10237 を参照)。新しい 'SimpleKeyGenerator' はそのようなシナリオのために複合キーを使用する。

Spring 4.0以前

Spel式では、パラメータの値を以下のように連結することをお勧めします。 key="#checkWarehouse.toString() + #isbn.toString()") org.springframework.cache.interceptor.ExpressionEvaluator はオブジェクトを返すので、これはうまくいくと思います。 int を指定する必要はありません。

衝突確率の高いハッシュコードとしては、あなたは はできません。 キーとして使用することはできません。

このスレッドで誰かが T(java.util.Objects).hash(#p0,#p1, #p2) を使うことを提案した人がいましたが、これはうまくいきませんし、この方法は簡単に壊れてしまいます。 SPR-9377 :

    System.out.println( Objects.hash("someisbn", new Integer(109), new Integer(434)));
    System.out.println( Objects.hash("someisbn", new Integer(110), new Integer(403)));

私の環境では2行とも-636517714と表示されます。

追伸:実はリファレンスドキュメントでは

@Cacheable(value="books", key="T(someType).hash(#isbn)") 
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

キーは一意であるべきなので、この例は間違っていて、誤解を招くので、ドキュメントから削除されるべきだと思います。

P.P.S. また、以下を参照してください。 https://jira.springsource.org/browse/SPR-9036 にも、デフォルトの鍵生成に関する興味深いアイディアがあります。

正確を期すため、また数学/コンピュータサイエンス的な事実として、組み込みハッシュと異なり セキュア 暗号化ハッシュ関数 MD5 や SHA256 のような、このような関数の特性により IS このタスクは絶対に可能ですが、毎回計算するのはコストがかかりすぎる可能性があります。