ラベル Java の投稿を表示しています。 すべての投稿を表示
ラベル Java の投稿を表示しています。 すべての投稿を表示

2014年10月14日火曜日

MyBatisで実行したInsertの戻り値が「-2147482646」を返す

掲題の問題発生から解消までの一部始終です。

今まで動いていたプログラムがある日突然、正常系処理が通らないようになり、
原因を調べてみたところ、MyBatisの処理を呼び出した後の返却値が
「-2147482646」となっていることがわかりました。

その原因および原因究明までの経緯をメモしておきます。

発生原因

applicationContext.xmlに変更を加えていたため。

【元】

  <beans
      xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

【変更後】

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:spring-dwr="http://www.directwebremoting.org/schema/spring-dwr"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
  http://www.directwebremoting.org/schema/spring-dwr http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

 <context:annotation-config />
 <context:component-scan base-package="~~~~~~" />
アノテーションによるComponentScanを利用しようとして、いくつかのスキーマ定義を
読み込ませたことが悪かったようです。

根源

調べてみてもわからず。

追加xmlスキーマを読んで挙動が変わったか、annotation-configの宣言で
ライブラリの読み込まれる順番、初期値などが変化したのかわかりませんが、
これ以上追う事はやめました。


発生経緯から、その他調べたこと

今回の件とは違うのですが、エラーコードで調べていくと幾つかの解決案が
ネット上に出ていたので、備忘録的にメモしておきます。

やったこと

機能追加でソースを修正し、その後発生。
現象が発生している箇所は全く修正していない。


エラーコードで調べてみると、英文サイトで以下が見つかりました。

http://www.just4e.com/mybatis-3.0.4/docs/reference/org/apache/ibatis/executor/BatchExecutor.html

public static final int BATCH_UPDATE_RETURN_VALUE
Constant Value: -2147482646 (0x800003ea)


要は、バッチ更新モードの戻り値が、「-2147482646」だという事。



バッチ更新モードに変えたつもりもないし、そのようなソース変更履歴もない。

しかも、他の人のパソコンで実行した結果を確認してもらうと「1」 = 登録結果行数
こっちが正しいはずなので、私の実行環境がおかしい。
※当然、同じプログラムを実行してます。



調べてみると、以下のような会話が。
https://groups.google.com/forum/#!searchin/mybatis-user/2147482646%7Csort:relevance/mybatis-user/ddRPVRzwvlc/n5I_1YgKqSsJ

SqlSession session = sqlMapper.openSession(ExecutorType.SIMPLE);


BatchModeで開くのではなく、Simpleモードで開く。ということなので、
ソースを探してみたところ、数か所でopenSession(); を発見。
初期値がどうなっているかは調べもしないでとりあえず (ExecutorType.SIMPLE) を指定して再ビルド:実行



結果、変わらず。

その後、mybatisのドキュメントより初期値を発見。初期値はSIMPLEでした。
http://mybatis.github.io/mybatis-3/ja/configuration.html

既定値の変更(defaultExecutorType)ができるようなので、設定名でソースを検索したが結果、該当なし。


別観点としてデータベースとのコネクション周りを疑い、他のデータベースへ接続しても現象同じ。


というところで調査をやめて、コミット単位のモジュールで調査して行ったところ
上記の原因へ至ったという次第でした。


まとめ

今回の発生起因は「annotationを使いたい」ために色々といじったことが原因でした。
実装の根幹を変えるような変更を行う際は十分注意しましょう。

2014年9月17日水曜日

Mybatisを使う中でのTips (軽め

使っているライブラリのバージョンは、3.0.4です。
マニュアルをきちんと読めばわかる内容なので、自分用メモです。

IF文について


else はありません。
比較演算子は、 != か、 == です
ELSEを使いたければ、chooseを。

例) Order Byを可変にする例

OEDER BY
<if test="sortId != null and sortId!=''">
  ${sortId} ${sortType}
</if>
<if test="sortId == null or sortId == ''">
  COLA ASC
  ,COLB DESC
</if>

別途定義しているSQLを利用する方法


定義:

<sql id = "commonQuery">
SELECT 1
</sql>

呼び出し

<include refid="commonQuery"/>


2014年7月2日水曜日

javaでzipファイルを作成する

javaでzipな要件が出てきたのでちょっと書いてみました。

javaに関してはド素人なので文法やお約束などすっとばしてる可能性大ですがご容赦ください。


【やること】

・zipファイル名、対象のファイル、格納する際のパス加工を指定してzip処理を行う。
・元のファイルは特にいじらない。
・ディレクトリ指定された場合、ディレクトリ内のすべてのファイルを対象とする。


【実施環境】

CentOS6.5
java version "1.6.0_30"
OpenJDK Runtime Environment (IcedTea6 1.13.3) (rhel-5.1.13.3.el6_5-x86_64)
OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode)


【注意点】

いろんな情報を見ていると、JRE1.6系では全角のファイル名が扱えないとか
何とか、いろんな情報が出ているようです。
その為の検証だったのですが、結果、問題ありませんでした。
⇒その後の検証で原因発覚。利用している解凍ツールが対応していただけでした。


ant.jarが持つ、Zip圧縮ツールを使うサンプルです。

【ソースの中身でちょっと分かりづらい仕様の説明】

・存在しないファイルを指定した場合、ゴミZipだけが残る事象が確認されたため
 回避するためにNotFoundExceptionを発生させています。
・絶対パス指定の場合、私の環境ではきれいにフォルダ構成まで作られてしまったため
 それを回避するためにZipEntryへは相対パス以下のフォルダ指定をするようにしました。
・ライブラリを、java.io.zipへ戻せるように、Encodingは外から指定可能とし、
 指定された場合のみ使うようにしました。



【ソース】


汎用性を持たせるため、2つに分けました。

----------------------------------------------------------------
ZipTest.java
----------------------------------------------------------------

import java.io.*;
import java.lang.*;
import java.util.*;
import java.util.ArrayList;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;

public class ZipTest{
  public static void main(String[] args){
    File  file;                 //作成するzipファイルの名前
    List<File> files = new ArrayList<File>();
    String baseDirectory = "";
    if (args != null && args.length > 2)
    {
      //引数1 zipファイル名
      file = new File(args[0]);
       
      //引数2 基準ディレクトリ
      baseDirectory = args[1];

      //引数3以降 対象ファイルのパス
      for (int i= 2;i<args.length;i++)
      {
        files.add(new File(args[i]));
      }
      System.out.println(files.size());
    }
    else
    {
      //demo
      file = new File("sample.zip");
      baseDirectory = "/tmp/sample/csv/";
      //圧縮対象を相対パスで指定
      files.add(new File("/tmp/sample/csv/あ.txt"));
      files.add(new File("/tmp/sample/csv/い.txt"));
      files.add(new File("/tmp/sample/csv/ああ.txt"));
      files.add(new File("/tmp/sample/csv/いい.txt"));
    }

    ZipCompressUtils zip;
    zip = new ZipCompressUtils(baseDirectory);

    try{
      zip.Compress(file,files);
    }
    catch (Exception e){
    }
  }
}

----------------------------------------------------------------


実行処理
----------------------------------------------------------------
ZipCompressUtils.java
----------------------------------------------------------------


import java.io.*;
import java.lang.*;
import java.util.*;
//import java.util.zip.ZipEntry;
//import java.util.zip.ZipOutputStream;
import org.apache.tools.zip.*;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

public class ZipCompressUtils
{
  //Private Declare
  static String _rootPath = null;
  static String _encoding = "MS932";
   
  //Constructor
  public ZipCompressUtils()
  {
  }
  public ZipCompressUtils(String rootPath)
  {
    _rootPath = rootPath;
  }
  public ZipCompressUtils(String rootPath , String encoding)
  {
    _rootPath = rootPath;
    _encoding = encoding;
  }
  public boolean Compress(File target , List<File> files) throws Exception {
    try{
      ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(target));
     encode(zos, files);
      if (_encoding != null)
      {
        zos.setEncoding(_encoding);
      }
     zos.close();
      return true;
    }
    catch (Exception e){
      target.delete();
      throw e;
    }
  }
  static void encode(ZipOutputStream zos, List<File> files) throws Exception {
    byte[] buf = new byte[1024];

    //File配列のLoop
    for (File f : files) {
      if (!(f.exists())){
        throw new FileNotFoundException();
      }
      //ディレクトリなら再帰
      if (f.isDirectory()) {
        encode(zos, Arrays.asList(f.listFiles()));
      } else {
        //ファイルの場合の処理
        String zipEntryPath = f.getPath().replace(_rootPath,"").toString().replace("\\", "/");
        ZipEntry entry = new ZipEntry(zipEntryPath);
        zos.putNextEntry(entry);
        InputStream is = new BufferedInputStream(new FileInputStream(f));
        for (;;) 
        {
          int len = is.read(buf);
          if (len < 0) break;
          zos.write(buf, 0, len);
        }
      }
    }
  }
}