Spring Data JPAストアドプロシージャ機能のテストに使用している簡単なストアドプロシージャがあります。
create or replace procedure plus1inout (arg in int,res1 out int,res2 out int) is
BEGIN
res1 := arg + 1;
res2 := res1 + 1;
END;
私のコードは:
@Repository
public interface AdjudConverDateSPRepository extends JpaRepository<AdjudConverDateSP, Long> {
@Procedure(name = "plus1")
Object[] plus1(@Param("arg") Integer arg);
}
@Entity
@NamedStoredProcedureQuery(name = "plus1", procedureName = "ADJUD.PLUS1INOUT",
parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class),
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res1", type = Integer.class),
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res2", type = Integer.class)
})
public class AdjudConverDateSP implements Serializable {
//stub to satisfy hibernate identifier requirement
@Id @GeneratedValue
private Long id;
}
OUTパラメータを1つ指定すると、すべてが正常に機能します。しかし、2番目のOUTパラメータを追加すると、エンティティ内にプロシージャが見つからないという例外が発生します。
Caused by:
org.springframework.data.mapping.PropertyReferenceException: No property plus1 found for type AdjudConverDateSP! at
org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.Java:75) at
org.springframework.data.mapping.PropertyPath.create(PropertyPath.Java:327) at
org.springframework.data.mapping.PropertyPath.create(PropertyPath.Java:307) at
org.springframework.data.mapping.PropertyPath.from(PropertyPath.Java:270) at
org.springframework.data.mapping.PropertyPath.from(PropertyPath.Java:241) at
org.springframework.data.repository.query.parser.Part.<init>(Part.Java:76) at
org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.Java:235) at
org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.Java:373) at
org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.Java:353)
@Procedure
には、メソッドの戻り値の型に直接バインドされているOUTパラメータが1つだけ必要なようです...
複数のOUTパラメータを処理するには、JPA APIを直接使用できます。
StoredProcedureQuery proc = em.createNamedStoredProcedureQuery("plus1");
proc.setParameter("arg", 1);
proc.execute();
Integer res1 = (Integer) proc.getOutputParameterValue("res1");
Integer res2 = (Integer) proc.getOutputParameterValue("res2");
...
次のように、@Procedure
アノテーションのoutputParameterName
paramを使用して、複数の出力パラメータの1つを返すように指定できます。
@Repository
public interface AdjudConverDateSPRepository extends JpaRepository<AdjudConverDateSP, Long> {
@Procedure(name = "plus1", outputParameterName = "res2")
Integer plus1(@Param("arg") Integer arg);
}
更新2019-06-24:
Spring Data JPA 2.2-RC1で複数の出力パラメーターがサポートされるようになりました https://spring.io/blog/2019/06/17/spring-data-moore-rc1-and-lovelace-sr9-released =
https://jira.spring.io/browse/DATAJPA-707
インターフェースメソッドはMapの戻り値の型を持つ必要があるだけなので、各出力パラメーターはキー名でアクセスできます。
@Repository
public interface AdjudConverDateSPRepository extends JpaRepository<AdjudConverDateSP, Long> {
@Procedure(name = "plus1")
Map<String, Object> plus1(@Param("arg") Integer arg);
}
Springはまだ複数のoutパラメータをサポートしていません。これには [〜#〜] jira [〜#〜] があります。