- 1 名前:デフォルトの名無しさん mailto:sage [2005/12/16(金) 11:54:44 ]
- 前スレ:
Java⇔RDBのMapping-Frameworkを語るThre Vol.3 ttp://pc8.2ch.net/test/read.cgi/tech/1090653286/ 過去スレ: 「Java⇔RDBのMapping-Frameworkを語るスレ Vol.2」(落ち) ttp://pc5.2ch.net/test/read.cgi/tech/1086315004/ 「Java⇔RDBのMapping-Frameworkを語るスレ」(落ち) ttp://pc5.2ch.net/test/read.cgi/tech/1049030272/ ●まずは、基礎知識と技術選択指針など [The Fundamentals of Mapping Objects to Relational Databases] (RDBに対するオブジェクトマッピングの基礎(英語)) ttp://www.agiledata.org/essays/mappingObjects.html [O/R-Mappingツールの比較サイト(英語)] ttp://c2.com/cgi-bin/wiki?ObjectRelationalToolComparison [Catalog of Patterns of Enterprise Application Architecture (PoEAA)] ttp://www.martinfowler.com/eaaCatalog/ あとは>>2以降
- 697 名前:デフォルトの名無しさん mailto:sage [2007/10/08(月) 20:48:34 ]
- >>694
プロパティとDBのフィールド名は一致させる必要はないぞ
- 698 名前:デフォルトの名無しさん mailto:sage [2007/10/08(月) 21:35:58 ]
- >>695-697
POJO内のメンバはDB上はこのフィールド、 のようなことはマッピングファイル?か何かに書いておけば Dbアクセスの時は意識せずに使える、 ORマッピングのツールはどれもそんなモンなんですか? 逆に、それはできないぞ、というモノもあるのでしょうか。
- 699 名前:デフォルトの名無しさん [2007/10/09(火) 01:09:02 ]
- >>698
EJB3.0だとこんな感じになるはず。 # ただ、なるべく一致させておいた方が不幸なことが起きないかも・・・ @Entity(name="ITEM") public class Item implements Serializable{ private int id = 0; @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="RENBAN",nullable=false) public int getId(){ return id;} public void setId(int id){ this.id=id;} private String title = null; @Column(name="SHOSEKI_MEI",nullable=false) public String getTitle(){ return title;} public void setTitle(String title){ this.title=title;}
- 700 名前:694 mailto:sage [2007/10/09(火) 01:21:50 ]
- 試しにCayenneでやってみますた。
作成されたBeanを見ると、 public static final String フィールド名_PROPERTY = "メンバ名"; という定数があって、これを使うようですね。 外部ファイルかアノテーションでやるのかと思ってましたが、 他のフレームワークでもこんなカンジなんでしょうか。 >>699 なるべく一致させたいのはやまやまですが、 ERを変えられるような立場ではないのです。orz EJB3.0だとアノテーションで指定するのですね。 参考になります、ありがとうございますた。
- 701 名前:デフォルトの名無しさん mailto:sage [2007/10/09(火) 13:04:01 ]
- JPAはEJB3から独立してSEで使えるから便利だよ
NetBeansだとテーブルから全部自動で作られるし
- 702 名前:デフォルトの名無しさん mailto:sage [2007/10/09(火) 20:24:11 ]
- >>701
NetBeans以外では自動で作ってくれるツールをしらない?
- 703 名前:デフォルトの名無しさん mailto:sage [2007/10/09(火) 21:34:41 ]
- プラグインを用意することなくデフォで使えるってのが大きいだけだろ
- 704 名前:デフォルトの名無しさん mailto:sage [2007/10/10(水) 01:27:45 ]
- >>702
知ってる
- 705 名前:デフォルトの名無しさん mailto:sage [2007/10/10(水) 01:31:27 ]
- >>701
きしだタソ乙
- 706 名前:デフォルトの名無しさん mailto:sage [2007/10/12(金) 06:45:53 ]
- >>702
WTP2.0
- 707 名前:デフォルトの名無しさん [2007/10/12(金) 22:52:01 ]
- 結論:DAOでOK マッピングイラネ
- 708 名前:デフォルトの名無しさん mailto:sage [2007/10/12(金) 23:05:37 ]
- DAOでOKって、マッピング使っても使わなくてもDAO使うだろ。
- 709 名前:デフォルトの名無しさん mailto:sage [2007/10/13(土) 03:12:15 ]
- >>707
ありえないほどバカだな
- 710 名前:デフォルトの名無しさん mailto:sage [2007/10/13(土) 08:51:12 ]
- DAO内で自分でSQL発行じゃね?
- 711 名前:デフォルトの名無しさん mailto:sage [2007/10/13(土) 10:59:52 ]
- >>710
その場合でも、手動マッピングはするわけだが
- 712 名前:デフォルトの名無しさん mailto:sage [2007/10/13(土) 11:32:35 ]
- わかった!>>707はマッピングせずに
M a p を そ の ま ま 使 う ん だ よ !
- 713 名前:デフォルトの名無しさん mailto:sage [2007/10/13(土) 13:24:55 ]
- ものによってはMapそのままでも悪くないと思うけどな
キー値の取得がプロパティの取得につながるし ただ、HashMapとかそのままつかうのだけは禁止 キー値が存在しない場合Exceptionをかえすような実装ならOK
- 714 名前:デフォルトの名無しさん mailto:sage [2007/10/13(土) 17:00:59 ]
- まーた、Map厨発生か。
が、キー値なしで例外は納得した。
- 715 名前:デフォルトの名無しさん mailto:sage [2007/10/15(月) 15:09:20 ]
- 実は Microfost Data Access Objects のことなのかも知れん。
- 716 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 12:47:53 ]
- ResultSetだってRowSetだってmapベースだろ
DelphiだってBCBだってスクリプト系だって
- 717 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:05:52 ]
- こいつは何をいっているんだ?
- 718 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:19:27 ]
- はじめから道具ありきで、どっかで道に迷っちゃうんだろ
若い奴らは大変なんだよきっと
- 719 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:28:44 ]
- Map系ってのはMapインターフェースを実装したものではなくて
名前で値を引っ張るものってことだろ。 何もおかしいことはない。
- 720 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:42:06 ]
- どうしてわざわざオブジェクトに情報を詰めなおすのか
知っているか?
- 721 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:42:10 ]
- 以前、このスレだか過去スレだかに、Map、Mapと騒ぐ奴がいたのな。
その流れを汲んでの話なんだよ。 自分で間違ったことを言っていないつもりなのだろうけど、 このずっと前からのスレの流れ的には空気読めてないんだよ。 しばらくROMってろ。
- 722 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:52:41 ]
- >>720
JavaがLightWeightじゃないから
- 723 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 17:47:29 ]
- >>721
それは知っているが、そんな昔の狂ったやつなんてもう今はいないだろう Mapのように名前を使ってアクセスする場合何が問題だったのかだけがわかって使っていればおけ VCLのようにラッパクラスをそのまま入れないこと、存在しないキーに対して 取得しようとしたときに例外を発生させることがきまっていれば問題はない
- 724 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 17:52:59 ]
- >>719
おまえの頭がおかしいということはわかった。
- 725 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 18:07:58 ]
- "存在しないキーに対して取得しようとしたときに例外を発生させる"
これが必要なのはなんで? と思ったが、nullが戻ってきたんじゃデータが無いのか項目自体がないのかが判別できないのか それ以外の理由もある?
- 726 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 18:48:26 ]
- そもそもDBにnull入れないほうがよくない?
- 727 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 21:53:40 ]
- そうか?
- 728 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 22:33:48 ]
- NULLが無いほうが楽ではあるかもな色々と
ただ、Oracleのような、空文字列がNULLであるようなDBMSではNULLを 避けようが無いだろう
- 729 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 22:41:00 ]
- NullはDBに必要だろ
- 730 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 22:42:28 ]
- (商用で)一番普及してしまっているOracleの仕様にはモニョるものがある罠・・・。
ただnullはアレで便利な面もあるので、ここらは宗教論だろう。
- 731 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 01:04:31 ]
- DBにNULLが全くいらないってのが
どんな状況かわからん。
- 732 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 02:44:06 ]
- Mapを使う時点で、静的型言語の利点を失っている気がする。
だったら、RoRのActiveRecordのほうがよっぽど使いやすい。
- 733 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 09:26:04 ]
- HOGE <> 1 な条件で、HOGE が NULL なレコードが取得できないのが
直感的じゃないと思うので、検索列には NULL は勘弁して欲しいところだ。
- 734 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 11:59:11 ]
- >>733
nullがほしいならnullもor条件いれればいいじゃない 直感的ではないというのは同意だが、SQLにとってnullは特別な値だから仕方がないか
- 735 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 12:11:08 ]
- 検索の際の特別扱いだけでなく、
NULLありのカラムはインデクス張る際にも実装上の制約があったりするし、 単純にホスト言語のデータ型とマッピングする際にもやや面倒が生じるので、 少なくとも意味のあるデフォルト値が考えられるようなエンティティなら、 NULLの代わりにデフォ値突っ込んだほうが楽は楽な気がする。 ま、常にそうできるというわけでもないが。
- 736 名前:デフォルトの名無しさん mailto:sage ネタだよ [2007/10/17(水) 12:23:44 ]
- むしろプログラム言語で3値論理をきれいに扱えないのがおかしい
- 737 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 13:08:35 ]
- C#のnullは3値論理だ
- 738 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 13:09:54 ]
- Javaなら3値普通に扱えるだろ・・・
- 739 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 15:11:51 ]
- C.J.Dateたんは第五正規形まで正規化すればnullなんていらんだろ派だね。
- 740 名前:デフォルトの名無しさん mailto:sage [2007/10/18(木) 11:31:41 ]
- >>733
条件を () で括って最後に is true
- 741 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 11:43:49 ]
- Daoは1テーブルごとに1クラス作成して、CRUDのメソッドがあるのが普通なのでしょうか。
1:nのテーブルがあって、一覧を表示する詳細な検索画面などでどうしても結合が必要な場合や条件が複雑になる場合は その画面専用?のメソッドを作成するものなのでしょうか。
- 742 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 16:28:16 ]
- というか、それはORマッパがやるだろ。
- 743 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 17:46:11 ]
- テーブル単位でCRUDってのは大概O/Rマッパがやってくれる
連結は製品次第 DBのようにテーブル状に結果が入るほうがいい場合もあるし そのつど連結先を取ってくるほうがいい場合もあるしなんとも
- 744 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 18:06:18 ]
- DAOやORマッパは手段なのに、
目的の方を「どうするのが普通でしょうか?」って おかしくね?
- 745 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 18:34:43 ]
- そういうヤツは、O/Rマッパの仕様に合わせてテーブル設計とかしそうで怖いよな。
COBOLerお得意の横長DBとか。 まあ、漏れは直でSQLゴリゴリ出来る人なので、条件・結合が複雑だったら SQLを直書きではあるな。
- 746 名前:デフォルトの名無しさん [2007/10/21(日) 21:12:53 ]
- テーブル単位でCRUDするだけがORマッパーの役割と思ってる奴多くね?
- 747 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 21:14:14 ]
- 少ないと思う
- 748 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 21:39:36 ]
- >>539
って結局JSPで、DTOからコード値をgetして、 <% if (sex.equals("1") {%>男 ... (taglibとか) みたいなのを書くってことでしょうか。 それともDTOにUser#getSexName、getSexCodeを自前で準備するものですか。 これだと自動生成が大変なのですが。。。 前にViewでマッピングしようとするとコネクションが切断?されてるから例外になったり、 マッピングを自動でするような機能がなかったりして断念したことがあるのですが。
- 749 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 23:47:14 ]
- >>748
その例外はO/Rマッパ依存の部分でしょ たとえばJPAのリファレンス実装であるToplinkは参照専用のコネクションを開くので問題ない それにリソースファイルで扱う場合も多いし、すべてアプリやライブラリなど実装次第としかいえんぞ
- 750 名前:デフォルトの名無しさん [2007/10/22(月) 16:02:03 ]
- そこはentityにisMan()isWomen()を持たせたら?
- 751 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 19:55:03 ]
- >>748
定数値と表示名称のマップをアプリケーションスコープに保存して ELでアクセスしたりとか DBに持たせてEntityの2次キャッシュにしたりとか 色々方法はあると思う
- 752 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 19:57:38 ]
- 俺はマップをアプリケーションスコープに入れる派
- 753 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 20:38:01 ]
- >DBに持たせてEntityの2次キャッシュにしたりとか
これってどういうことなん?詳しくお願いしたいかもー。
- 754 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 21:59:39 ]
- 定数マスタとかをDBに持ってる場合
Hibernateなどの2次キャッシュ機能を使えば アプリレベルでEntityを共有できる これを通常のEntityと関連付けてLazyロードさせれば Entityだけで名称表示を行える まぁでも設定とか色々と面倒かも
- 755 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 22:36:37 ]
- >>754
おー、なるほど、どうもです。
- 756 名前:デフォルトの名無しさん mailto:sage [2007/10/23(火) 01:30:51 ]
- O/Rマッパでキャッシングはデフォっしょ
やってないほうが少ないのでは? おかげでLAZYが便利 ただ、hibernateではセッション明けとかないとダメかもね
- 757 名前:デフォルトの名無しさん mailto:sage [2007/10/23(火) 21:41:49 ]
- キャッシングした場合、定数マスタかなんかが更新されるタイミングっていつになるのでしょうか。
例えば、DB直接いじって定数テーブル?に1行追加して、htmlの画面で<option>がふえてねーじゃん!てことにならない?
- 758 名前:デフォルトの名無しさん mailto:sage [2007/10/23(火) 22:10:44 ]
- そら、なるんだろうなぁ
- 759 名前:デフォルトの名無しさん [2007/10/23(火) 22:37:32 ]
- だめやん
- 760 名前:デフォルトの名無しさん [2007/10/23(火) 22:43:49 ]
- ORマッパー=はいばね
な件
- 761 名前:デフォルトの名無しさん mailto:sage [2007/10/24(水) 01:52:07 ]
- ORマッパ使おうが使うまいが
キャッシュ対象は読み取り専用のデータだけでしょ プロパティファイルのDB格納版というか
- 762 名前:デフォルトの名無しさん mailto:sage [2007/10/24(水) 01:58:30 ]
- リソースファイルも変更時には配備しなおしてVM再起動が必要だろ
それと同じこと
- 763 名前:デフォルトの名無しさん mailto:sage [2007/10/24(水) 01:59:36 ]
- >>757
キャッシュ対象データはO/Rマッパーを使って更新する
- 764 名前:デフォルトの名無しさん mailto:sage [2007/10/24(水) 13:48:23 ]
- >>757
だからデフォルトのキャッシュ設定はoff。 キャッシュ側で短めの有効期限を設定したり、 動的な更新を想定しないテーブルのみに使ったりする。 クラスタの場合はDB直接編集でなくとも不整合が起こるので、 分散キャッシュ(OSSだとJBoss TreeCacheが有名)を使う事もある。
- 765 名前:デフォルトの名無しさん mailto:sage [2007/10/24(水) 22:27:37 ]
- >>757
管理者機能でマスタ更新とか作ったりするが、それじゃだめ? DB直接いじってもボタン押したらキャッシュ読み直しみたいな。 大抵そんな機能を要求されるとマスタに好きなだけ追加削除更新したいって言い出すけどな。 性別なんて男性・女性・不明ぐらいでいいのに全部編集したい!とかいう客は珍しくない。
- 766 名前:デフォルトの名無しさん mailto:sage [2007/10/25(木) 10:28:47 ]
- 性別マスタの編集で追加削除ってどんな時代だろう
- 767 名前:デフォルトの名無しさん mailto:sage [2007/10/25(木) 20:51:23 ]
- 時代っていうか顧客。
「MTFTS」「MTFTV」「その他」「不明」とかぞろぞろあるんじゃね?
- 768 名前:デフォルトの名無しさん mailto:sage [2007/10/25(木) 23:19:50 ]
- すまんすまん。性別は極端な例だったか。
最近はいろいろと考慮して、男・女の2択はまずやらないわけです。 そういう人からすると”不明”てのはあんまりよろしくないからね。 単純にデフォルトの表示を空白とか"-"にして必須選択にしないってのがうちの会社の流れです。
- 769 名前:デフォルトの名無しさん [2007/11/08(木) 20:01:01 ]
- iBatis をつかってて、Generics関係で質問です。
以下のような ProductDao といったクラスを作り、 Product エンティティをリストで返すメソッドを作りました。 public List<Product> listProduct() throws Exception { SqlMapClient sqlMap = MyIBatisUtil.getSqlMap(); return sqlMap.queryForList("Product.selectAll"); } これで -Xlint:unchecked 付きでコンパイルすると、以下の警告が出ます。 警告:[unchecked] 無検査変換です 検出値 : java.util.List 期待値 : java.util.List<jp........Product> return sqlMap.queryForList("Product.selectAll"); 警告 1 個 <Product>はどこにつければいいのでしょうか? return sqlMap.queryForList<Product>("Product.selectAll"); とやったら「シンボルを見つけられません」とでてしまました。
- 770 名前:デフォルトの名無しさん mailto:sage [2007/11/08(木) 20:15:48 ]
- >>769
原因はsqlMap.queryForListの戻り値が 型指定なしListになってるっぽいところじゃないかな。 キャストしても確か出たと思うので、 メソッド宣言の頭に@SuppressWarning("unchecked")をつけるとか。
- 771 名前:デフォルトの名無しさん mailto:sage [2007/11/08(木) 20:31:40 ]
- 1.4までのライブラリはそうなるの多いね
でも、JPAは5.0前提なのにキャストが必要で警告でるってのは納得いかないんだぜ・・・
- 772 名前:デフォルトの名無しさん mailto:sage [2007/11/08(木) 21:00:45 ]
- レスどうもありがとうございます。
なるほど、com.ibatis.sqlmap.client.SqlMapExecutor#queryForList()が Generics なしでビルドされているから(1.4デモ使えることを前提にしているから) 仕方がないということですね。 今作っているのは、自分の勉強もかねていて Genericsはあまり使ったことがないので、 生産性を度外視して極力 Generics を使っているのですが、 いろんなところでこの警告がでて直そうとすると疲れます。 >>769 で示したのは Dao の Impl クラスなのですが、 Dao のインターフェースクラスでは public List<Product> listProduct() throws Exception; というように、Dao を呼ぶ側に対しては Generics 付きで公開したいので、 >>770 のように @SuppressWarnings("unchecked") をつけて黙らせることにしました。 これで -source 1.5 -Xlint:unchecked をつけても、このメソッドでは警告が出ないようになりました。 勉強になりました。どうもありがとうございました。
- 773 名前:デフォルトの名無しさん mailto:sage [2007/11/08(木) 21:27:11 ]
- Genericsは1.4以前のコードとの相性もあるが、リフレクションとも相性が悪いからね。
外部との連携が多いと利点を活かしきれないことも多いとは思う。 JDBC4.0があと2年もすれば普及すると思うけど、 >>769の手間をデータベース開発元がやってくれるから凄く楽になる。 SQLを外だしするってだけでも恩恵はでかいからiBatisは残るだろうけど。
- 774 名前:デフォルトの名無しさん mailto:sage [2007/11/10(土) 00:44:24 ]
- ibatisをspring等と連携しないで使うには、
SqlMapClientをpublic static等で参照できるようにして #setUserConnectionでjava.sql.Connectionをセット、queryXXXを実行するで問題ないでしょうか。 あと、いまいちSqlMapSessionの存在意義などがわからないのですが・・・
- 775 名前:デフォルトの名無しさん [2007/11/11(日) 18:18:46 ]
- struts+ibatisで開発しています。
DBの接続先をibatisのxmlに記述しているのですが、 参照するDBが複数になってしまった場合どんな感じでやるのがベストだと思いますか? 単純に設定ファイル追加か、追加されたDBのコネクションを取得してセットしてやるが候補なのですが、おかしいかな。
- 776 名前:デフォルトの名無しさん mailto:sage [2007/11/11(日) 21:22:36 ]
- sqlMapClientはDB接続先をひとつしか管理できないよね?
なので設定ファイルを追加して、SqlMapConfig も複数にするしかないような気が。 ibatisのサイトのチュートリアルの7ページを改造してみた。 以前も同じような方式でやったが、ほかにいいアイデアがあればおれも教えてほしい。 public MyAppSqlConfig { private static final SqlMapClient sqlMap_A ; private static final SqlMapClient sqlMap_B ; static { try { // A用 String resource = "com/ibatis/example/sqlMap-config_A.xml"; Reader reader = Resources.getResourceAsReader (resource); sqlMap_A = SqlMapClientBuilder.buildSqlMapClient(reader); // B用 resource = "com/ibatis/example/sqlMap-config_B.xml"; reader = Resources.getResourceAsReader (resource); sqlMap_B = SqlMapClientBuilder.buildSqlMapClient(reader); } catch (Exception e) { throw new RuntimeException ("Error initializing MyAppSqlConfig class. Cause: " +e); } } public static SqlMapClient getSqlMapInstance_A(){ return sqlMap_A; } public static SqlMapClient getSqlMapInstance_B(){ return sqlMap_B; } }
- 777 名前:デフォルトの名無しさん mailto:sage [2007/11/11(日) 21:50:05 ]
- >>776
thx。 やっぱそういう感じになるか。 >>774の#setUserConnection?をつかってもできそうな、できなさそうな
- 778 名前:デフォルトの名無しさん [2007/12/14(金) 00:33:18 ]
- HibernateToolsでhbmファイルを自動生成しようとしてるんですが、
関連があるテーブルだと勝手に多重度が設定されますよね。 one-to-manyとか。 あれを自動で設定されたくないんですが、 自動生成時にオプションとかでオフにできないものでしょうかm(_ _)m
- 779 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 01:50:45 ]
- DBから関連はずせば?
- 780 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 09:23:05 ]
- DBの制約残したままでやりたいのですm(_ _)m
- 781 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 21:34:57 ]
- DBの構造コピーして、関連はずしてマッピング作成ってのがてっとりばやそうだな
- 782 名前:デフォルトの名無しさん mailto:sage [2007/12/18(火) 08:58:11 ]
- そうかやっぱり関連外す手しかないか...
ありがとうm(__)m
- 783 名前:デフォルトの名無しさん [2007/12/25(火) 14:20:30 ]
- HibernateのSessionで質問があります。
いま自分がヘルプでアサインされた案件が(Struts+)Spring+Hibernateなのですが、 DAOの作り方が以下のようになっています。 スーパークラス:Org.springframework.orm.hibernate3.support.HibernateDaoSupport 各業務のDAO:HibernateDaoSupportをextendsする。 OracleのXML DB SQL関数を使いたいという理由で、HQLもcriteriaでもなく 生SQL を使っている。 各業務DAOでは、以下のようなコードになっています。 例: public List getHogeTableEntity() { 〜 Session session = super.getSession(); SQLQuery query = (SQLQuery) session.getNamedQuery("...."); ScrollableResults sr = query.scroll(); 〜 } 質問1.: このメソッドの中で、sessin.close()が呼ばれていなかったり、ScrollableResults.close()も 呼ばれていないのですが、これはNGですよね? session には clear() というメソッドもありますが、close()とはどう違うのでしょうか? 質問2.: 上記のケースとは違いますが、似た質問です。 技術評論社のSpring入門なんかの本を見ると、以下のようなコード(例.p274)があります。 public List findPerson() { return getHibernateTemplate().find("from person"); } ここでは close() がよばれていませんが (そもそも org.springframework.orm.hibernate3.HibernateTemplate には close() がない) これはこれでいいのですよね?
- 784 名前:デフォルトの名無しさん mailto:sage [2007/12/25(火) 15:24:48 ]
- 環境によるけど、コネクションを各自にまかせるタイプと、
フレームワークなどがそれらを完全にコントロールしてユーザーは コネクションを勝手に閉じたりしてはいけないタイプがある。 トランザクションがどの境界でコミットされるかなど、重要なことは多い。 わからないことがあったら普通に素直に聞いたほうがいいよ。 とくにあとからヘルプで入った場合はチーム内での暗黙のルールとかあると思うし。
- 785 名前:デフォルトの名無しさん mailto:sage [2007/12/26(水) 00:39:23 ]
- > 質問1.:
> session には clear() というメソッドもありますが、close()とはどう違うのでしょうか? Hibernate は取得したオブジェクトを Session にキャッシュしている。 そのキャッシュのクリアが clear() で行える。 ただし、この関数を呼び出してしまうと、Session#save() で永続化しているが、まだDBにコミットして いないアクションさえもクリアしてしまう。 close() はそのセッションの破棄を意味する。
- 786 名前:デフォルトの名無しさん mailto:sage [2007/12/26(水) 00:45:09 ]
- > 質問2.:
Spring の HibernateTemplate は基本的にすべての作業を HibernateCallback インターフェイス内で 行う。 この HibernateCallback には、Object doInHibernate(Session session) という関数が定義されており、 この関数に渡される Session は Spring が破棄してくれる。 さらに、Spring では HibernateCallback を実装しなくてもある程度は実行できるようにいくつかの簡単な 関数を HibernateTemplate で提供してくれている。 > return getHibernateTemplate().find("from person"); も、そのうちの一つ。これを、HibernateCallback を使用して実装すると以下のような感じになる。 return getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Query query = session.createQuery("from person"); return query.list(); } }); Spring のソースを追えばすぐに分かると思う。
- 787 名前:デフォルトの名無しさん mailto:sage [2007/12/26(水) 00:54:03 ]
- このように、Hibernate+Spring の組み合わせの場合、基本的には Session#close() などを Spring 側に任せるように
することが出来る。 >>784 も言及しているが、この辺は各プロジェクトでどのような扱いにしているのかで話が変わってくるので、 聞いた方が早い。 ただ、HibernateDaoSupport を継承したとしても、HibernateCallback の中でない限りは Spring が Session を自動的に 閉じたりすることを期待できない気もする。 とはいえ、AOP を使用して閉じるようにしているのかもしれないので断言は出来ない。 だけど、ScrollableResults は自力で閉じないとムリなような気が・・・。
- 788 名前:デフォルトの名無しさん mailto:sage [2007/12/26(水) 01:28:46 ]
- Struts+Spring+Hibernateの組み合わせなら、AOPで閉じてるかSession In Viewで閉じてるはず。
てか、俺はそうした。
- 789 名前:デフォルトの名無しさん mailto:sage [2007/12/26(水) 02:08:53 ]
- どこの現場もフレームワークの上にさらにかぶせてる場合も多いからなんとも
オープンソースだけにソースに手が入ってる可能性も高いしね 断言は危険
- 790 名前:デフォルトの名無しさん mailto:sage [2007/12/26(水) 17:42:16 ]
- みなさんレスどうもありがとうございます。
ORMapper は iBatis しか使ったことがなかったので Hibernate は初めてなのですが、とても参考になりました! >>785 clear() の役割はわかりました。 たしかに Hibernate にはその特徴として 「永続化コンテキスト」というのがあるが、 そのキャッシュを破棄するということですね。 >>786-788 Spring の HibernateTemplate と組み合わせる場合は、Spring のなかで Session が管理されているので、プログラマは意識しなくてよいというのも理解しました。 自分が理解した仕組み: >>787 のように Spring AOP を使っていることが前提となるが、 1.context.xml で、transactionManager や、Transaction 管理させるAOPの設定をしておく 2.AOPで、たとえば update* というメソッドを AOP の範囲と設定しておく 3.update*() に処理が移ると、Session が確保される(Commons DBCP などを使っている場合、pool からひとつとってくる) 4.getHibernateTemplate().find() すると、内部で 3. で得たSession に対し DB アクセスが行われる (ThreadLocal 経由で DAO に Session が渡されるのかな) 5.update*() が終わると、トランザクションが commit され、session も close() される。 Spring のソースをDLして見てみましたが、>>786 で示していただいたソースは、 HibernateTemplate#find(String, Object[]) と同じものですね。
- 791 名前:783 mailto:sage [2007/12/26(水) 17:43:24 ]
- ( >>790 も私です)
こちらの状況ですが、フレームワーク担当に聞いたり、OSSをラップしているローカルフレームワークの ソースを読んだところ、以下の状況でした。 ・トランザクションの管理は、context.xml の AOP で行っている。 ・独自に Interceptor や Adviser のようなクラスをつくり、そこで管理はしていない。 ・実際には HibernateDaoSupport と業務DAO の間にローカルフレームワークの抽象クラスがあるが、 ここでもトランザクション管理/Session 管理はしていない。 業務DAO が >>783 になっていることを告げると、フレームワーク担当もどうしたらいいかわからないということで 調べることになりました。 ということで、以下のように考えました。 ・ScrollableResults は、Spring をうまく使っていようがいまいが、自分で close() する必要がある ・super.getSession() した場合、AOP の範囲の外を出たときに、session が自動的に close() されるかどうか 調べる必要があり うーん、サンプル作って実験してみるか・・・ ちなみに AOP は以下のように設定しています。
- 792 名前:783 mailto:sage [2007/12/26(水) 17:50:18 ]
- <!-- TransactionManager -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"><ref bean="sessionFactory"/></property> </bean> <!-- Transaction proxy --> <bean id="autoTransactionProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <value>*Service</value> </list> </property> <property name="interceptorNames"> <list> <value>tsInterceptor</value> </list> </property> </bean> 続く
- 793 名前:783 mailto:sage [2007/12/26(水) 17:50:47 ]
- 続き
<!-- interceptor --> <bean id="tsInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager"><ref bean="transactionManager"/></property> <property name="transactionAttributeSource"><ref bean="tsAttribute"/></property> </bean> <!-- attribute --> <bean id="tsAttribute" class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource"> <property name="properties"> <props> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="insert*">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="delete*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> 何度も連投すみません。以上です。
- 794 名前:デフォルトの名無しさん mailto:sage [2007/12/27(木) 00:18:15 ]
- >>783
お前がプロジェクトに対して発言権があるかどうかはわからないが、 おれは出来る限りHibernateDaoSupport を使うときには HibernateCallback で実装を進めるようにしてもらったほうがいいと思ってるし、 方針が曖昧なようならそう提案してみてはどうだろう? そうすることによって ・ Session の境界をコントロールしやすくなる。 (HibernateTemplateがネストしたときには下位のセッションが上流に合流する) ・session の close() 忘れが無くなる。 (これはテスト実行時にデッドロック的な挙動を引き起こしたりする) という利点がある。 OpenSessionInViewパターンは一番シンプルなんだが、 View 層に処理が渡ってから DB にアクセスするしにいったりする挙動が 三層モデル大好きな奴らから理解を得られない場合があるしやめたほうがいい。 複数画面をまたいでオブジェクトを引き回すときには結局Hibernateのセッション切れるんで、 あんまり有利でないことも多いし。
- 795 名前:デフォルトの名無しさん mailto:sage [2007/12/28(金) 00:38:31 ]
- >>790
誤解のないように言っておくが、iBatisでもSpringと組み合わせれば似たようなことができるよ
- 796 名前:デフォルトの名無しさん [2008/01/16(水) 01:23:47 ]
- Hibernateで、主キーはOracleのトリガで生成する場合で聞きたいのですが、
その場合にマッピングファイルに定義するIDジェネレータは SelectGenerator ですよね。 公式のチュートリアルにこんなんあったんですが、 ------------ <id name="id" type="long" column="person_id"> <generator class="select"> <param name="key">socialSecurityNumber</param> </generator> </id> ※person_idがトリガで払出した代理キーで、socialSecurityNumberが自然キーらしいです ------------ 僕が実現したいテーブルに自然キーはないので(ユニークになるカラムもPKだけ)、 以下のようにしたいのですが、keyが必須だとエラーがでました。 ------------ <id name="id" type="long" column="person_id"> <generator class="select" /> </id> ------------ 自然キーで指定するフィールドもないので、どうやって<id>タグ書けばいいのか分かりません。 どなたか教えてもらえないでしょうかm(_ _)m
- 797 名前:デフォルトの名無しさん [2008/01/20(日) 09:43:59 ]
- Mr. Persisterには関連のマッピング機能は実装済みですか?
|

|