はじめに
株式会社アルパカコネクトというWebサービスを運営しています。
このたび、弊社がバックエンドで使用しているSpring Bootを3.Xにアップデートすることになり、その際にHibernate 6.Xへのアップデートも必要となりました。
その際、
- JPQLを使い続けたい
- ストアドファンクションも使いたい(MySQL)
というニーズを満たすためにちょっと苦労したので、その備忘録になります。
朗らかに破壊的アップデート
ここでは触れませんが、javaxからjakartaへの以降を皮切りにHibernate周りも多数のアップデートが入り、JPAのブログでノリノリで解説されたりしています。
破壊的なアップデートもハイテンションに書けば許される感じがしていてナイスです。
しかし、いざストアドファンクションのマイグレーションを進めようとしたとき、記事のなかにはわずかにFunctionContributorの存在が匂わされているだけで、ググれどもググれども正解にたどり着けませんでした。
FunctionContributorの存在を知ったあとも公式ドキュメントらしいものにもたどりつけず、Stack Overflowなどの断片的な情報を頼りに実装まで進めることになりました。
頼みの綱のTwitterで検索しても1件しか引っかからなかったのは悲しかったです。
――ストアドファンクションを使わなければいいんじゃ、と思ったあなた。僕もそう思います。
けれども、そのためにFE資産を大量に修正する必要がでてくるので、BEだけのアップデート作業でなんとか済ませたかったんですよね……。
さて、前置きが長くなりましたが、始めます。
before
Heibernate 5.x時代でJPQLとストアドファンクションを併用するために、以下のページのようにMySQLDialectを使用していました。
しかし、Hibernate 6.XからはMySQLDialectがなくなってしまった、というのが今回の経緯です。おのれ。
after
ざっくりと以下の2つが必要になります。
- FunctionContributorを使う
- META-INF以下に所定のフォルダ&ファイルを作り、該当クラスを記述する
1.FunctionContributorの実装
public class MyFunctionContributor implements FunctionContributor {
@Override
public void contributeFunctions(FunctionContributions functionContributions) {
functionContributions.getFunctionRegistry().registerNamed(
"method_name",
functionContributions.getTypeConfiguration().getBasicTypeRegistry()
.resolve(StandardBasicTypes.STRING)
);
}
}
registerNamed()
メソッドでストアドファンクションの名前を指定し、
functionContributions.getTypeConfiguration().getBasicTypeRegistry() .resolve(StandardBasicTypes.STRING)
で解決時の型を指定します。
ここではStringに指定しています。
2.META-INF以下に所定のフォルダ&ファイルを作り、該当クラスを記述する
上記のクラスを作って実装するだけではJPQLでクエリの発行までは行けても、マッピングの段階でエラーがでるようです。
現状、上記の実装はJAVAのSPIを使用しているようで、META-INFフォルダにファイルを作成する必要があります。
(拡張子なしのプレーンテキストファイル形式のファイルです)
■パス
/src/main/resources/META-INF/services/org.hibernate.boot.model.FunctionContributor
■ファイルの中身
上記パスで作成したファイルに、以下の記述を行います。
packageには、先程作成したMyFunctionContributorが置かれている場所を指定してください。
{package}.MyFunctionContributor
Hibernateが起動時にFunctionContoributorを使用しているクラスを見つけるために必要なようです。
僕の場合、これで実際のDBを使ってのテストが通るようになりました。
終わりに
「MyFunctionContributor」でぐぐっても 8 件しか出てこなかったり、Twitterでも 1件しかでてこなかったりするので、困ってるヒトはあまりいなさそうなんですが、
今後、Spring bootを3.Xにアップデートせざるを得なくなった方で、ストアドファンクションを使い倒している方の助けになれたら幸いです。