最新の安定バージョンについては、Spring Data JPA 3.5.4 を使用してください!

ストアドプロシージャー

JPA 2.1 仕様では、JPA 条件クエリ API を使用してストアドプロシージャを呼び出すサポートが導入されました。リポジトリメソッドでストアドプロシージャメタデータを宣言するための @Procedure アノテーションを導入しました。

以下の例では、次のストアドプロシージャを使用します。

例 1: HSQL DB の plus1inout プロシージャの定義。
/;
DROP procedure IF EXISTS plus1inout
/;
CREATE procedure plus1inout (IN arg int, OUT res int)
BEGIN ATOMIC
 set res = arg + 1;
END
/;

ストアドプロシージャのメタデータは、エンティティ型で NamedStoredProcedureQuery アノテーションを使用して構成できます。

例 2: エンティティの StoredProcedure メタデータ定義。
@Entity
@NamedStoredProcedureQuery(name = "User.plus1", procedureName = "plus1inout", parameters = {
  @StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class),
  @StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class) })
public class User {}

@NamedStoredProcedureQuery には、ストアドプロシージャの 2 つの異なる名前があることに注意してください。name は、JPA が使用する名前です。procedureName は、データベース内のストアドプロシージャの名前です。

リポジトリメソッドからストアドプロシージャを複数の方法で参照できます。呼び出されるストアードプロシージャーは、@Procedure アノテーションの value または procedureName 属性を使用して直接定義できます。これは、データベース内のストアドプロシージャを直接参照し、@NamedStoredProcedureQuery を介した構成を無視します。

または、@NamedStoredProcedureQuery.name 属性を @Procedure.name 属性として指定できます。valueprocedureNamename のいずれも構成されていない場合、リポジトリ方式の名前が name 属性として使用されます。

次の例は、明示的にマップされたプロシージャを参照する方法を示しています。

例 3: データベースで "plus1inout" という名前の明示的にマップされたプロシージャを参照しています。
@Procedure("plus1inout")
Integer explicitlyNamedPlus1inout(Integer arg);

次の例は前の例と同等ですが、procedureName エイリアスを使用しています。

例 4: procedureName エイリアスを介してデータベース内の名前 "plus1inout" を持つ暗黙的にマップされたプロシージャを参照します。
@Procedure(procedureName = "plus1inout")
Integer callPlus1InOut(Integer arg);

以下は、明示的なアノテーション属性の代わりにメソッド名を使用している点を除いて、前の 2 つと同じです。

例 5: メソッド名を使用して、EntityManager で暗黙的にマップされた名前付きストアドプロシージャ "User.plus1" を参照します。
@Procedure
Integer plus1inout(@Param("arg") Integer arg);

次の例は、@NamedStoredProcedureQuery.name 属性を参照してストアドプロシージャを参照する方法を示しています。

例 6: EntityManager で明示的にマップされた名前付きストアドプロシージャ "User.plus1IO" の参照。
@Procedure(name = "User.plus1IO")
Integer entityAnnotatedCustomNamedProcedurePlus1IO(@Param("arg") Integer arg);

呼び出されるストアドプロシージャに単一の出力パラメーターがある場合、そのパラメーターはメソッドの戻り値として返されます。@NamedStoredProcedureQuery アノテーションで複数の出力パラメーターが指定されている場合、@NamedStoredProcedureQuery アノテーションで指定されたパラメーター名をキーとして Map として返すことができます。

ストアドプロシージャが ResultSet を返す場合、メソッドが Map 戻り値の型を宣言しない限り、Java は単一のメソッド戻り値しか返せないため、OUT パラメーターは省略されることに注意してください。

次の例は、ストアドプロシージャに複数の OUT パラメーターがあり、@NamedStoredProcedureQuery として登録されている場合に、複数の OUT パラメーターを取得する方法を示しています。パラメーターメタデータを提供するには、@NamedStoredProcedureQuery の登録が必要です。

例 7: エンティティの StoredProcedure メタデータ定義。
@Entity
@NamedStoredProcedureQuery(name = "User.multiple_out_parameters", procedureName = "multiple_out_parameters", parameters = {
  @StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class),
  @StoredProcedureParameter(mode = ParameterMode.REF_CURSOR, name = "some_cursor", type = void.class),
  @StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class) })
public class User {}
例 8: 複数の OUT パラメーターを返す
@Procedure(name = "User.multiple_out_parameters")
Map<String, Object> returnsMultipleOutParameters(@Param("arg") Integer arg);