質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

Q&A

0回答

794閲覧

JPAからのStoredProcedureコール

h.t.0210

総合スコア6

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

0グッド

0クリップ

投稿2018/03/22 13:31

編集2018/03/23 05:34

前提・実現したいこと

複数件の依頼に対して、JPAのStoredProcedureQuryを利用して、
件数分プロシージャコールを行い登録する処理を実装しています。
全て成功した場合のみcommitという作りにしています。
データベースはOracleです。

発生している問題・エラーメッセージ

問題は、StoredProcedureQueryのexecuteメソッドを繰り返しコールすると、
その都度カーソルがオープンされてしまい、300に到達した時点でORA-01000(最大オープン・カーソル数を超えました。)でエラーになってしまっています。

該当のソースコード

lang

1try{ 2 fac = Persistence.createEntityManagerFactory("xxx"); 3 em = fac.createEntityManager(); 4 tx = em.getTransaction(); 5 6 StoredProcedureQuery spq; 7 spq = em.createStoredProcedureQuery("YYYY.ZZZZ"); 8 spq.registerStoredProcedureParameter(1, Object.class, ParameterMode.IN); 9 spq.registerStoredProcedureParameter(2, Object.class, ParameterMode.IN); 10 spq.registerStoredProcedureParameter(3, Short.class, ParameterMode.OUT); 11 spq.registerStoredProcedureParameter(4, Short.class, ParameterMode.OUT); 12 tx.begin(); 13 for (List<String> rec : csv) { 14 String aa = rec.get(0); 15 String bb= rec.get(1); 16 spq.setParameter(1, aa); 17 spq.setParameter(2, bb); 18 // 実行 19 spq.execute(); 20 21 // エラーチェック 22 if(...){ 23 tx.rollback(); 24 return; 25 } 26 } 27 tx.commit(); 28}catch(Exception e){ 29 throw e; 30}finally{ 31 if(em != null)em.close(); 32 if(fac != null)fac.close(); 33}

lang

1CREATE OR REPLACE PACKAGE YYYY 2AS 3 /** ステータスコード **/ 4 G_RET_NORMAL NUMBER := 0; 5 G_RET_SQLERROR NUMBER := 1; 6 G_RET_PARAMERTER NUMBER := 2; 7 G_RET_DUPLICATION NUMBER := 3; 8 G_RET_NO_EXIST NUMBER := 4; 9 10 /** エラーNO **/ 11 G_ERR_NO_SUCCESS NUMBER := 0; 12 G_RET_ERROR NUMBER := 1; 13 14 PROCEDURE ZZZZ 15 ( 16 I_AAA IN TABLE_A.AAA%type, 17 I_BBB IN TABLE_A.BBB%type 18 O_STATUS OUT NUMBER, 19 O_ERROR_NO OUT NUMBER 20 ); 21END YYYY; 22/ 23 24CREATE OR REPLACE PACKAGE BODY YYYY 25IS 26 PROCEDURE ZZZZ 27 ( 28 I_AAA IN TABLE_A.AAA%type, 29 I_BBB IN TABLE_A.BBB%type 30 O_STATUS OUT NUMBER, 31 O_ERROR_NO OUT NUMBER 32 ) 33 IS 34 nCOUNT NUMBER := 0; 35 BEGIN 36 /* 入力パラメータチェック */ 37 ・・・ 38 39 /* データ存在チェック */ 40 BEGIN 41 SELECT 42 COUNT(1) 43 INTO 44 nCOUNT 45 FROM 46 TABLE_A 47 WHERE 48 AAA = I_AAA 49 AND BBB = I_BBB 50 ; 51 EXCEPTION 52 WHEN OTHERS THEN 53 O_STATUS := G_RET_SQLERROR; 54 O_ERROR_NO := SQLCODE ; 55 RETURN ; 56 END ; 57 IF nCOUNT > 0 THEN 58 O_STATUS := G_RET_DUPLICATION; 59 O_ERROR_NO := G_RET_ERROR ; 60 RETURN ; 61 END IF; 62 63 /* データ登録 */ 64 BEGIN 65 INSERT INTO 66 TABLE_A 67 ( 68 AAA, 69 BBB 70 ) VALUES( 71 I_AAA, 72 I_BBB 73 ); 74 EXCEPTION 75 WHEN OTHERS THEN 76 O_STATUS := G_RET_SQLERROR; 77 O_ERROR_NO := SQLCODE ; 78 RETURN ; 79 END ; 80 O_STATUS := G_RET_NORMAL ; 81 O_ERROR_NO := G_ERR_NO_SUCCESS ; 82 RETURN ; 83 EXCEPTION 84 WHEN OTHERS THEN 85 O_STATUS := G_RET_SQLERROR ; 86 O_ERROR_NO := SQLCODE ; 87 RETURN ; 88 89 END ZZZZ; 90END YYYY; 91/ 92

試したこと

プロシージャ内の処理を空にしても同様のエラーとなったため、おそらくプロシージャコール自体でカーソルを作成しているものと思われます。
V$OPEN_CURSORを確認したところ、確かに「BEGIN プロシージャ名; END;」というOPENが増幅していました。
JPAのStoredProcedureQueryを使わずにjava.sql.CallableStatementで呼び出したら、トランザクションの制御を含めてうまくいきましたので、JPA側の問題ではないかと思います。
ただ、コードの統一性を考慮して、実装はあくまでJPAで行いたいと考えています。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/03/22 14:26

ストアドの設計として間違えてるとしか思えないんだが
h.t.0210

2018/03/23 01:53

回答いただきありがとうございます。ストアドではトランザクションの制御は行わず、処理としては存在チェックをして、あればエラー、なければインサートをしています。
h.t.0210

2018/03/23 05:33

JPAのStoredProcedureQueryを使わずにjava.sql.CallableStatementで呼び出したら、トランザクションの制御を含めてうまくいきましたので、JPA側の問題ではないかと思います。
退会済みユーザー

退会済みユーザー

2018/03/23 13:28

ちなみにJPAの実装はサードパーティーに任されています。
h.t.0210

2018/03/30 09:15

開発期間も限られている為、CallableStatementで対応しました。そもそもJPAのストアドの対応がなされたのも最近のバージョンみたいなので、今回のような不具合?はあるのかもしれないですね。単に使い方の可能性の方が高いとは思いますが。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問