JPA を使用して Oracle ストアド プロシージャを実行しようとしています。以下に示すように、クエリを作成し、query.getResultList() を介してストアド プロシージャを呼び出すと、結果を取得できます。
@Autowired
EntityManager em;
public List<MyEntity> callStoredProcedure(String paramOneValue, String paramTwoValue)
{
StoredProcedureQuery query = em.createStoredProcedureQuery("storedProcedureName");
query.registerStoredProcedureParameter("paramOneName", String.class, ParameterMode.IN);
query.registerStoredProcedureParameter("paramTwoName", String.class, ParameterMode.IN);
query.registerStoredProcedureParameter("results", Void.class, ParameterMode.REF_CURSOR);
query.setParameter("paramOneName", paramOneValue);
query.setParameter("paramTwoName", paramTwoValue);
query.execute();
List<MyEntity> result = new ArrayList<MyEntity>();
for(Object item: query.getResultList())
{
/* mapping my object to the entity and adding to the collection
result.add(new MyEntity(item));
}
return result;
}
ただし、これはあまりエレガントではありません。
以下のコードのようにエンティティ マッピングを使用しようとすると、errpr が発生します。
org.springframework.orm.jpa.JpaSystemException: CallableStatement から結果を抽出中にエラーが発生しました"
と
java.sql.SQLException: 列名が無効です
プロシージャが呼び出された後、エンティティにマップしようとしているとき
@NamedStoredProcedureQueries({
@NamedStoredProcedureQuery(name = "MyStoredProcedure",
procedureName = "storedProcedureName",
resultClasses = {MyEntity.class},
parameters = {
@StoredProcedureParameter(name = "paramOneName", mode = ParameterMode.IN, type = String.class),
@StoredProcedureParameter(name = "paramTwoName", mode = ParameterMode.IN, type = String.class),
@StoredProcedureParameter(name = "results", mode = ParameterMode.REF_CURSOR, type = void.class)
})
})
@Entity
public class MyEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private long id;
@Column(name="MY_FIRST_COLUMN")
private String myFirstColumn;
// Related Properties
}
// And declaring as repository
@Repository
public interface IMyRepository extends JpaRepository<MyEntity, Long {
@Procedure
List<MyEntity callMyStoredProcedure(@Param("paramOneName") String paramOneName,
@Param("paramTwoName") String paramTwoName);
}
この問題をいくつかの方法で解決しようとしました。エンティティ カスタム マッピング @SqlResultSetMapping を使用query.getResultList
し、 をList<MyEntity>
. ただし、例外は常に同じです。
JPA がストアド プロシージャから列情報を取得できないようです。
列名を再確認したところ、ストアド プロシージャによって取得された列と一致していましたが、データベースにそのような列を持つ実際のテーブルがないことを追加する必要があります。
ポムから…
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.2.Final</version>
</dependency>
マッピングを機能させるには、ストアド プロシージャを特定の方法で記述する必要がありますか (PS 残念ながら、ストアド プロシージャの定義にアクセスできません)。
結果セットをエンティティにマップできるようにするために、ストアド プロシージャによって取得されたものと同じ列を持つデータベース内の物理的なテーブルまたはビューが必要ですか?
助けてくれてどうもありがとう