0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Spring Boot3でどうしてもJPQL * ストアドファンクションを使いたくてFunctionContributorと向き合うことになったときの備忘録

Last updated at Posted at 2023-05-29

はじめに

株式会社アルパカコネクトという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」でぐぐっても 件しか出てこなかったり、Twitterでも 1件しかでてこなかったりするので、困ってるヒトはあまりいなさそうなんですが、
今後、Spring bootを3.Xにアップデートせざるを得なくなった方で、ストアドファンクションを使い倒している方の助けになれたら幸いです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?