フィブログ

うさんくさいプログラムの備忘録とか。

seasar2にexcella導入すると実行時にException吐いてうまく動かない

seasar2プロジェクトにexcellaを導入してExcel出力しようという局面がありました。

しかしexcellaのjarファイルをseasar2プロジェクトに取り込んで動かしたところExcel出力時にエラーが出る。

なんでだろう・・・と悩んでましたが原因がわかりました。

 

どうもseasar2apache-poi3.0が同梱されているようでこれがクラスパス内に存在していた。

一方導入したExcellaはpoi3.1で動作してる。

seasar2が起動したときに先に3.0のほうを読み込んでいたらしくexcellaで利用する際にバージョンが合わなくてエラーしてたっぽい。

 

seasar2からpoi3.0を削除したら難なく動いた。

 

EntityManagerを利用したレコードロック時のタイムアウト設定

EntityManagerを使用してDBとのやりとりをしてる時に壁にぶち当たりました。

排他制御をしつつ更新を行わないといけないときロックどうやるん?ってとこです。

そもそもDB接続ですら既存お任せ状態なのでアクセス方法すら知らない。

なんて考えてると意外と簡単にロックかけられました。

 

EntityManagerで取得レコードにロックをかける

単純にロックをかけるだけの場合は以下のような感じでできます。

EntityManager em;
private void test(){
    // DBからSELECTする
    Query query = em.createQuery("SELECT a FROM UserMst a", UserMst.class);
    UserMst entity = em.getSingleResult();
    
    // SELECTしたレコードをここでロックする
    em.lock(entity,  PESSIMISTIC_WRITE);
    
    // PESSIMISTIC_WRITEは共有ロック
    // PESSIMISTIC_READは排他ロック らしい。
    // この辺はDBの知識が入りそうなので調べてね。
}

 このようにEntityManager.lockメソッドでロックをかけれます。

第一引数にロックをかけるレコード情報、第二引数にロックタイプを指定します。

 

EntityManagerのロックにタイムアウト時間を指定

で、今回やりたいのは単純なロックじゃないです。

前記の状態で、User①がレコードロック中にUser②が同じレコードをロック有りで取得しにいくと、User①のレコードロックが解除されるまでずーっと待ちます。今回やりたいのは、User②がレコードロックを取得できない場合、即時エラーにしたいのです。SQLで書くなら FOR UPDATE NO WAITを実現したい。ので、タ イムアウト設定するのがこちら

 

EntityManager em;
private void test(){
    // DBからSELECTする
    Query query = em.createQuery("SELECT a FROM UserMst a", UserMst.class);
    UserMst entity = em.getSingleResult();
    
    // 設定用のマップオブジェクトを作成
    Map<String,String> map = new HashMap<String,String>();
    //"javax.presistance.lock.timeout"にタイ ムアウト時間を設定(0の場合はNOWAITの意味)
    map.put("javax.presistance.lock.timeout","0");
    
    try{
        // SELECTしたレコードをここでロックする。
        em.lock(entity,  PESSIMISTIC_WRITE, map);
    }catch(LockTimeoutException  e){
        // タイ ムアウトしたらLockTimeoutExceptionが飛んできます
        //例外処理はここに書いてね
    }
}

 タイムアウトとか細かな設定はMapで渡すことになってるようなので

設定用のMap変数を作成。

"javax.presistance.lock.timeout"というキーにタイムアウト時間を設定するので

タイムアウト時間を値に設定します。

その後、lockメソッドの第三引数に上記のMap変数を渡してあげればOK

ロックタイムアウトの時はLockTimeoutExceptionがスローされてくるので

エラー処理はキャッチして書きましょう。

 

EntityManagerなんて使わずにネイティブなSQL書かせてくれれば楽なのになぁ。

JQueryのfunction内ですんなりreturnしないとき

プログラム書いてるとチェック処理メソッドなどでNGが判明したら

即座にfalseをreturnしてメソッド終わらせるなんてことはよくやると思いますが

なんかJQueryで書いてるとreturnで抜けないことがある

 

 

function(resultList){
  $.each(resultList, function(obj){
    if(obj == false){
       return false;  // ここで抜けたいけど何故か抜けない
    }
  });
  
  return true;
}

 なんでだろうと思ってたんですが、原因はeachの所為でした。

JQueryのeachの中ではreturnは特別な意味を持つようです。

each内で書くreturnは

 return true : continue

 return false: break

の意味になるそうです。

 

つまり、上記のソースだとbreakしてるだけになるので

eachを抜けて最終行のreturn trueが実行されます。

 

これ知らないとハマるわ。

JQueryを全く知らない技術者がJavaScriptやJQueryを始めるときに抑えておくポイント1

前書き

JavaScriptJQueryも全く分からなかった時にはまったポイントなどをまとめます。

今流行りらしいJavaScript、この世から消えてなくなればいいのにと日々願っています。

 

前提知識

Java、C、VBなどのプログラムが組める人

(変数とか関数などの概念がわかる人)

 

JQueryって何?

JQueryJavaScriptを使用したスクリプト言語みたいなものです。

JavaScriptだったらごちゃごちゃ書かなければいけないものをJQueryなら

少ないコードで書けたりします。

 

何ができんの?

WebアプリケーションでHTMLを動的に編集したりなんかに使います。

Ajaxを用いてサーバとの通信したりですとかもやれます。

例えば、ボタンクリックしたら特定の場所を非表示にするとか

テキストをクリックしたらダイアログ出すとか、文字色変えるとか、CSSのクラスを追加するとか、HTML系に関することだったらほぼ何でもできるかと。

 

抑えるべきポイント

じゃあ開発やるときに概念として抑えるポイントは何か

変数に関数を突っ込むという概念

 JQueryというかJavaScriptでは変数に関数を突っ込むのがザラにあります。

//変数に関数を突っ込む
var  test = function(){
    alert("フィブログラム");
};

//メイン関数内で呼び出せる
function main(){
  test();
};

main関数が呼び出された際の動きは下記のとおりです

main呼び出し→test変数にアクセス→test変数は関数が入ってるので関数呼び出されalertが実行される。

イメージとしてはC、C++にある関数ポインタに近いです。

Javaで言うならメソッドだけ定義されたクラスだと思ってくれればいいかと。

これ、すごい、多用します。

 

関数の引数に↑の関数が指定できる

JavaScriptは変数に型定義なんてものはありません。

VBでいうなら全部Valiant型かなんかです。

厄介なのが関数の引数に上記で書いたタイプの変数が渡せることです。

//4.execute内で呼び出されて実行される
var  test = function(){
    alert("フィブログラム");
};

var  execute = function(method){
    
    //3.引数でもらった関数を実行(引数methodの中身はtext変数)
    method();
};

//1.メイン関数が実行される
function main(){
 
 //2.executeにtest変数を引数として渡して呼び出す
  execute(test); 
};

 そろそろわけわかんなくなってきましたね。

JavaScript系の関数は引数に型が書かれないので引数の中身が何者なのか非常にわかりづらいです。

呼び出し元で何が渡されてきているのかを確認、意識することがキモになります。

引数の中身をいきなり定義できる

上記のプログラムですが、下記のように書くこともしばしばあります。

 

//4.execute内で呼び出されて実行される
var  execute = function(method){
    
    //3.引数でもらった関数を実行
    method();
};

//1.メイン関数が実行される
function main(){
 
 //2.executeの引数として関数を直接書いて渡す
  execute(function(){
      //※前のソースで書いてたtest変数の内容を直接引数の中に書きだす
      alert("フィブログラム");
  }); 
};

ひとつ前のソースと全く同じですが、書き方が若干違います。

引数に直接関数を定義することができます。めちゃソース追いにくい。

 

 関数を呼び出すときに引数が足りなくても問題ない

Javaなんかでは引数の数ってかなり重要ですよね。

オーバーロードなんかしてると引数の数によって呼び出されるメソッドが変わってきます。

ただ、JavaScriptではその辺まったくないです。

 

//4.execute内で呼び出されて実行される
var  execute = function(text, loseFlg){
    
    if(loseFlg){
      // loseFlgが渡されて且つtrueだった場合のみ表示
      alert(text + ":J.avaScriptには勝てなかったよ・・・。");
    }else{
      // 渡されなかったり、falseだったら表示されない
      alert(text + ":J.avaScriptなんかに負けない!。");
    }
    
};

//1.メイン関数が実行される
function main(){
 
 // 1.「フィブ:J.avaScriptなんかに負けない!」を表示
 execute("フィブ");
 
 // 2.「フィブ:J.avaScriptには勝てなかったよ・・・。」を表示
 execute("フィブ",true);
};

一方は第二引数なし。もう一方は第二引数ありです。

 これ、両方同じ関数が呼ばれます。

引数を指定しなかった場合、何がわたってくるかはちょっとわかりませんが、

(undefineかnullかなんかだと思う)文法エラーにはなりませんし

普通に許容されます。

Javaとかやってるとかなり馴染みがありません。

まとめ

JavaScriptとかJQueryとかをやるうえでまず上記を理解するとソースが読みやすくなると思います。

js系の優秀なIDEはほとんどないであろうなので、トレースしていくにはかなり鍛練が必要になります。

引数の中に関数が定義されててその中で関数が定義されててその中で・・・

なんて追っていくことも多いので、その辺の概念を理解しましょう。

全く知らない状態で既存ソース読むと割とハマります。

あとは鍛練です。

初回はここまで。

次からはJQueryに寄った話を書いていく予定。