🔨

[Quarkus] OneToManyフィールドでLazyInitializationExceptionが発生する問題と解決法

2022/10/15に公開

こんにちは。今回はQuarkusで一対多(もしくは多対一)のフィールドを持つモデルのキャッシュの注意点について書いていこうと思います。

キャッシュと注意点

Quarkusでは、モデル定義したクラスに対して@Cacheableアノテーションをつけることによってデータをキャッシュすることができます。キャッシュ済みのデータはデータベースを介さないため、頻繁にアクセスするようなモデルでは速度の向上が見込めます。
しかし、一般的なフィールドでは普通にキャッシングするだけで良いのですが、OneToManyフィールドなどではそのままでは上手く動きません。POSTしたときや1回目のPUTでは問題なく動作するのですが、2回目のPUTからLazyInitializationExceptionが発生します。公式サイトのキャッシュの欄には対処法が載っていたのですが、中盤にちらっと書いてあるだけだったので見落としてしまい、1週間ぐらい詰まってました・・・。

解決法

というわけで公式サイトを見れば解決法が書いてあるのですが、軽くまとめておきます。
解決法は簡単で、コレクションやリレーションのフィールドに対して@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)アノテーションを付けるだけです。
特に理由が書いてないのですが、多分書き込みの際に外部キーかなにかが不整合を起こしてしまうのを防ぐために読み込みでのみキャッシュを使うようにする必要があるのではないかと思います。(違っていたらすみません)

まとめ

ManyToOneフィールドで発生するLazyInitializationExceptionへの解決法でした。
公式サイトに書いてあることではありますが、調べても全然出てこなくて苦労したので記事にしてみました。もし参考になった方がいれば幸いです。

参考

https://ja.quarkus.io/guides/hibernate-orm#caching

Discussion