- PR -

Update処理について

1
投稿者投稿内容
ぱちぱち
常連さん
会議室デビュー日: 2007/03/05
投稿数: 31
投稿日時: 2007-06-25 18:06
こんにちは。

hibernateのUpdate処理についてお聞きしたいと思います。
TESTTB entity = new TESTTB('a', 'b', 'c');
TESTTBDAO.Update(entity);

と処理部で記述しているのですが、イメージとしては'a'がPKで、'b','c'がUpdateしたいフィールドのデータです。
この場合、SQLだと
 Update TESTTB (B,C) values ('b','c') where A = 'a'
とhibernate側で実行されるのを期待しているのですが。

表示されたExceptionでは
org.springframework.orm.hibernate3.HibernateSystemException: not-null property references a null or transient value:
と、他フィールドの値を要求されました。(例えばこの場合はTESTTBのEフィールド)

not NULL指定してるフィールドでひょっとしてInsertしたがっているかなと思ってしまうのですが、hibernate側ではどのような処理をされているのでしょうか?

お分かりになる方ございましたら、よろしくお願いします。。
朝日奈ありす
大ベテラン
会議室デビュー日: 2007/05/02
投稿数: 189
お住まい・勤務地: 最北の地
投稿日時: 2007-06-25 18:28
ナル制約違反
ぱちぱち
常連さん
会議室デビュー日: 2007/03/05
投稿数: 31
投稿日時: 2007-06-25 18:41
ありがとうございます、ヌル制約違反でしょうか?

という事は
 Update TESTTB (B,C) values ('b','c') where A = 'a'
このようなSQLを発行したい場合は、ロジックが違うか、
hibernateではそういう規則。
という事ですね。

多分、前者だと思いますが・・。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-06-25 18:42
Hibernateに(JPAにも)SQLのUPDATEと同等の機能はありません。
get()やload()などで取得したエンティティのプロパティを更新し、
必要に応じてflush()すれば更新がDBに永続化(⇒SQLのUPDATE)されます。

ちなみに、save()でもINSERTが実行されるとは限りません。
OracleなどではSEQUENCEの採番だけ行わている可能性があります。

[追記]
UPDATEと同等の機能が「ない」というと語弊がありますね。
3.0あたりからbulk updateのサポートも追加されているので。
[/追記]

[ メッセージ編集済み 編集者: あしゅ 編集日時 2007-06-25 18:59 ]
ぱちぱち
常連さん
会議室デビュー日: 2007/03/05
投稿数: 31
投稿日時: 2007-06-25 19:01
あしゅさん、ありがとうございます。

という事はもう一度取得した後に、全てのデータをセットしたentityを
update();させると言う事ですね。。
SQLを一個余分に投げる必要が出てくるんですね(PKのみしかない場合)。
ん〜・・。

やっぱりSQLの方がいい気が・・。
あしゅさん、ありがとうございました。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-06-25 19:30
引用:

ぱちぱちさんの書き込み (2007-06-25 19:01) より:
SQLを一個余分に投げる必要が出てくるんですね(PKのみしかない場合)。
ん〜・・。

やっぱりSQLの方がいい気が・・。


そんな事ないですよ。

例えば、業務系のWebアプリだと
「一覧→編集→更新」という流れになることが多いと思うのですが、
HibernateやJPAではSELECTは最初の一覧を取得する時だけで実装できます。

このような遷移を行う場合は、
個々のリクエスト毎にHibernateのSessionが分かれてしまうわけですが、
以前のSessionで取得したEntityをHttpSessionに格納してUIから編集し、
更新を反映させる際に再度関連付けを行って永続化させることもできます。

この再関連付けに利用するのがupdate()メソッドです。

さらに、Webでは一般的にレコードの排他ロックは行えないので
更新されているかチェックを行わなければならない(⇒楽観的ロック)
場合もありますが、この行バージョンのチェックもlock()で自動化できます。

SQLのみでも更新時にSELECT FOR UPDATEが必要な場合も多いですよね。

このように、便利な機能はとても多いのですが、
SQL直接の場合とはアプリの設計からして変わってしまいますし、
多少のパラダイムシフトも必要なので導入が難しいんでしょうね。
ぱちぱち
常連さん
会議室デビュー日: 2007/03/05
投稿数: 31
投稿日時: 2007-06-25 19:39
あしゅさん、貴重なお話ありがとうございます。

なるほど、排他ロックなどの問題も考慮して、
フレームワーク側で管理してくれているんですね。
それで、設定をxmlに記載できるようにと。
ん〜・・なるほどですね。

今まで、hqlやらSQL一行で済むのに、なぜわざわざ
Entityやら、DAOやら、xmlを作らなければならず、
それでいて管理しやすくなったと言えるのか!

と思ってましたが、なるほどです。

開発者にとってはありがたいですね。
初心者に貴重なお話、ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)