これは、トホホなことです。
っま、いつものようにwebアプリの開発環境は、tomcat/spring/hibernate的なモノを使っておりまして、 CRUDに関しては特に、
- hibernateTemplate.save(hoge);
- hibernateTemplate.get(hoge);
- hibernateTemplate.update(hoge);
- hibernateTemplate.delete(hoge);
を、ゴシゴシと書くわけですね。
で、マスタ系のデータ(CSVファイル)をアップロードして、テーブルに更新するのに、最初のハナシの仕様では「総取り替え」だったので、さらに・・・
- hibernateTemplate.deleteAll(hoge);
で、コト足りたのです。ザッと単純なフローは、
- テーブルのデータ全削除
- CSVデータをテーブルにinsert
ははは・・・とても簡単!パイロット版を作って「よっしゃ!」っと、順調でした。
しかし、実際に現場でのヒアリングから、この仕様ではイカンことが判明し、行データ(件数)はCSVを使い、サーバーのテーブルに別途独自に保持された項目はイジラナイ・・・との仕様に変更になりました。
っま、思いついたフローの変更は・・・テーブルに変更Flgを追加しておいて、
- テーブルの全データの変更Flgをfalseに(念のため) ●
- CSVデータを順に読み込んで、
- 一致データがあれば、必要項目と変更Flgをtrueに更新
- 一致データがなければ、必要項目と変更Flgをtrueにしたレコードを追加
- テーブルの更新Flgがfalseのものを削除 ●
- テーブルの全データの変更Flgをfalseに ●
っま、こんなもんでしょ。っで、赤丸君 ● の、1,5,6 の箇所で、使ったのが、
- this.getSession().createQuery(deleteやらupdateのSQL文).executeUpdate();
みたいなネ。ちょちょいと動作確認できましたよ。おお、順調・ジュンチョウ・・・・。そして、念のため、連続的にアップロード処理を続けてみると、3回目(特定な処理タイミング)で、処理が帰ってこない・・・ガーン!
ログを見ると、ConnectionManagerがJDBCコネクションを開いたところで止まっている。この先はモチロンテーブルに更新が入るハズなのに・・・。
色々調べたら、Hibernateのキャッシュの問題・同一トランザクション内の実更新の順序の問題、っぽいのが気になったので、
- session.flush();
- session.clear();
やらを、色々入れて見るもダメ。泣きながら
- this.getSession().connection().createStatement().executeUpdate(deleteやらupdateのSQL文);
とかに「どーかヒトツ」っと、変更してみても・・・やはりダメ。
ああ、こりゃエライ壁にブチ当たってしまった!!!!!
でも、私は「カシコイ卑怯者」なので、以下で誤魔化すコトにした。例えば全フラグをfalseは・・・
List<Hoge> hoges = hibernateTemplate.find(ぜんぶ); for (int i=0; i<hoges.size(); i++) { hoges.get(i).setFlg(false); hibernateTemplate.update(hoges..get(i)); }
ざまあ見やがれ、100回アップロードしても止まらないぜぃ!!!!!
・・・・何十行の処理だからスムけど、これじゃ根本的に解決していない。
ああああ、カユイ。・・・いつかお前を「ヤッツけてやる」。
【だったらイイな】
本番環境で、サーバーやらフレームワークをセットアップしたら、問題なく動作するとか・・・ね。
【ひょっとして】
昨年の春に、解析の相談を受けた某システムが、同じような現象だったなぁ。これだったのカモですね。
【追記】
翌日にフッと気づきました。
- hibernateTemplate.find(flgがfalseを取り出すSQL);
- hibernateTemplate.deleteAll(上で取り出したList);
これでも実装できるじゃん。
あと、気になるのは
- hibernateTemplate.doExecute(hoge);
これをもうチョイ調べれば「解決」があるカモ!