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

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

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

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Java

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

Oracle Database 11g

Oracle DatabaseはRDBMSの商品です。具体的な発売商品として知られているのが、 Oracle9i、Oracle10g、Oracle 11gとOracle 12cです。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Q&A

2回答

3974閲覧

SpringBatch+iBatisでのOracle XMLTYPE型の取扱いについて

keisukestrat

総合スコア13

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Java

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

Oracle Database 11g

Oracle DatabaseはRDBMSの商品です。具体的な発売商品として知られているのが、 Oracle9i、Oracle10g、Oracle 11gとOracle 12cです。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

1グッド

1クリップ

投稿2016/10/28 06:37

###前提・実現したいこと
SpringBatch+iBatisを使用し、OracleのXMLTYPE型にINSERT/UPDATE/SELECTを行いたいと思っております。
容量の小さなXMLファイルをStringとして読み込み値をINSERTした場合は、正常に登録されますが、
ある容量以上のファイルになると下記エラーが発生します。

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

org.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation; uncategorized SQLException for SQL []; SQL state [72000]; error code [1461]; ORA-01461: LONG値はLONG列にのみバインドできます。 ; nested exception is java.sql.BatchUpdateException: ORA-01461: LONG値はLONG列にのみバインドできます。 at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:212) at org.springframework.batch.item.database.IbatisBatchItemWriter.write(IbatisBatchItemWriter.java:122) at org.springframework.batch.item.support.CompositeItemWriter.write(CompositeItemWriter.java:50) at org.springframework.batch.core.step.item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:171) at org.springframework.batch.core.step.item.SimpleChunkProcessor.doWrite(SimpleChunkProcessor.java:150) at org.springframework.batch.core.step.item.SimpleChunkProcessor.write(SimpleChunkProcessor.java:268) at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:194) at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:74) at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:371) at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:128) at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:262) at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:76) at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:367) at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:214) at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143) at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:248) at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195) at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:135) at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:61) at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60) at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:144) at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:124) at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135) at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:281) at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:120) at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49) at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:114) at org.springframework.batch.test.JobLauncherTestUtils.launchJob(JobLauncherTestUtils.java:151) at org.springframework.batch.test.JobLauncherTestUtils.launchJob(JobLauncherTestUtils.java:140) at com.hoge.foo.JobTest.testLaunchJob(JobTest.java:138) 中略 Caused by: java.sql.BatchUpdateException: ORA-01461: LONG値はLONG列にのみバインドできます。 at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:15000) at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:591) at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.ibatis.common.jdbc.logging.PreparedStatementLogProxy.invoke(PreparedStatementLogProxy.java:88) at $Proxy14.executeBatch(Unknown Source) at com.ibatis.sqlmap.engine.execution.SqlExecutor$Batch.executeBatchDetailed(SqlExecutor.java:642) at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeBatchDetailed(SqlExecutor.java:142) at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.executeBatchDetailed(SqlMapExecutorDelegate.java:775) at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.executeBatchDetailed(SqlMapSessionImpl.java:188) at org.springframework.batch.item.database.IbatisBatchItemWriter$1.doInSqlMapClient(IbatisBatchItemWriter.java:131) at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:209) ... 52 more

###該当のソースコード
Job定義は
ReaderにてXMLファイルの一覧を取得し、Readで1件ずつファイル名をProcessorに引き渡し、
ProcessorにてXMLファイルをString文字列でAAAAクラスに格納、
Writer(org.springframework.batch.item.database.IbatisBatchItemWriter)を使用し、格納となっています。

Java

1package com.hoge.foo; 2public class AAAA { 3 private Integer id; 4 private String xmldata; 5 //各セッター・ゲッター 6}

XML

1SqlMap.xml 2<sqlMap namespace="SqlMap_HOGE_TABLE"> 3 <insert id="insertForXMLTYPE" parameterClass="com.hoge.foo.AAAA"> 4 INSERT INTO HOGE_TABLE (ID,XML_DATA) VALUES(#id:DECIMAL#,#xmldata:OTHER#) 5 </insert> 6</sqlMap> 7 8SqlMapConfig.xml 9<sqlMapConfig> 10 <settings useStatementNamespaces="true"/> 11 <sqlMap resource="sqlmaps/SqlMap.xml"/> 12</sqlMapConfig>

###試したこと
ファイル自体の容量を小さくした場合に、正常にINSERTされることを確認しました。
org.springframework.jdbc.support.xml.Jdbc4SqlXmlHandlerをどうにかして、利用できれば、
と試してみましたが、組み込み方法がよくわからず、下記のように記載しましたが、エラーとなりました。

XML

1SqlMapConfig.xml 2<sqlMapConfig> 3 <settings useStatementNamespaces="true"/> 4 <sqlMap resource="sqlmaps/SqlMap.xml"/> 5 <typeHandler javaType="java.lang.String" callback="Jdbc4SqlXmlHandler"/> 6</sqlMapConfig>

また、PrepareStatementを使用し、SQLXML型でINSERTができるのではないかと考え、
下記の実装を行ってみましたが、エラーが発生しました。

Java

1 ・フィールドにてデータソースを定義し、@Autowiredで注入 2 private OracleDataSource ds; 3 4 ・処理メソッド 5 AAAA aaaa = new AAAA(); 6 OracleConnection conn = null; 7 OraclePreparedStatement pre= null; 8 try { 9 conn = (OracleConnection) ds.getConnection(); 10 StringBuilder sql = new StringBuilder(); 11 sql.append("INSERT INTO HOGE_TABLE (ID,XML_DATA) VALUES (?,?)"); 12 pre = (OraclePreparedStatement) conn.prepareStatement(sql.toString()); 13 int parameterIndex = 1; 14 pre.setString(parameterIndex++, aaaa.getId()); 15 SQLXML xmlObject = conn.createSQLXML(); 16 xmlObject.setString(aaaa.getXmlData()); 17 pre.setSQLXML(parameterIndex++, xmlObject); 18 19 pre.addBatch(); 20 pre.executeUpdate(); 21 22 } catch (Exception e) { 23 e.printStackTrace(); 24 }finally{ 25 SFDBUtils.closeQuietly(conn, pre, null); 26 }

XML

1データソースに@Autowiredを行う設定 2<bean id="test.XMLDB" class="oracle.jdbc.pool.OracleDataSource"> 3 <property name="URL" value="${XMLDB.jdbc.url}" /> 4</bean> 5また、このデータソースでも同様に試しましたが、エラーが発生するのは変わらず。 6<bean id="test.XMLDB" class="org.apache.commons.dbcp.BasicDataSource"> 7 <property name="driverClassName" value="oracle.jdbc.OracleDriver" /> 8 <property name="url" value="${XMLDB.url}" /> 9 <property name="username" value="${XMLDB.username}" /> 10 <property name="password" value="${XMLDB.password}" /> 11</bean>

Java

1発生したエラー 2java.sql.SQLException: サポートされない機能です。 3 at oracle.jdbc.driver.PhysicalConnection.createSQLXML(PhysicalConnection.java:17745) 4 at com.hoge.foo.JobTest.testLaunchJob(JobTest.java:102) 5 //省略

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

  • Java

java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02, mixed mode)

  • Spring Batch

spring-batch-2.1.6

  • Spring Beans

spring-beans-2.5

  • Oracle

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

A-pZ👍を押しています

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

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

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

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

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

guest

回答2

0

さっぱりアプローチが変わるので別回答とします。

原点に立ち返って、登録したいXMLを分解して、
フィールドをそれぞれ適切に保存する、というのはダメですか?

分解したいXMLの形があるなら、
・ trangというツールでXMLからdtdを逆作成(XMLの定義が作成されます)
・ xjcコマンドでbeanを作成(javaのオブジェクトが作成されます。)
・ java内ではXMLファイルをinにして、JAXBライブラリで分解
という感じで、割と手軽にXML <-> bean変換できます。

beanを作ってしまえば、コードでは、
JAXBContext jc = JAXBContext.newInstance(VirtFirewall.class);
StringReader reader = new StringReader(xml);
Unmarshaller u = jc.createUnmarshaller();
return (前もって作ったBean) u.unmarshal(reader);

こんな書きっぷりでBeanにはざっくり変換できます。
お役に立てなかったので、ご参考までに・・。

投稿2016/10/28 08:40

akio221

総合スコア716

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

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

keisukestrat

2016/10/31 08:19

別アプローチのご回答ありがとうございます。 本件に関しては、XSDの変更の可能性があり、JAXB変換・テーブルカラムを変更し対応する方法よりは、丸ごとXMLデータを格納しておきたいと考えておりました。 JAXBはSAX,StAXより変換が楽で便利ですよね!
guest

0

OTNの記事とクライアントのバグという記事がありました。
まず、怪しいのはクライアントのバグ説(バージョンが一致しているので)
http://www.projectgroup.info/tips/Oracle/errorcode/ORA01461.html

OTNの記事はXMLtypeの容量算定について
http://otn.oracle.co.jp/forum/thread.jspa?messageID=16001040

参考になりますでしょうか。

投稿2016/10/28 07:02

akio221

総合スコア716

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

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

keisukestrat

2016/10/28 08:05

早速の回答ありがとうございます。 OracleClientのバグ説については、ojdbc6_g.jarを更新して、実施したところ変化はありませんでした。 また、Oracle12c環境にてテスト同様に実施しましたが、変わらず・・・ 【Oracle】 Oracle Database 12c SE 12.1.0.2.0
akio221

2016/10/28 08:21

お役に立てず、申し訳ない。 1点、気になるのは、 >ojdbc6_g.jarを更新して、 *_g.jarは、デバッグ機能付きのJDBCなので、 通常のojdbc6.jarで、どう動くか、ですねぇ・・。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問