hibernate2 から hibernate3 の変更点 ネイティブSQL編

hibernate でネイティブSQLを発行したい場合 Session クラスの createSQLQuery を使用する。
hibernate2 の場合は下記の通りだった。

net.sf.hibernate.Session
    public Query createSQLQuery(String sql, String returnAlias, Class returnClass);
    public Query createSQLQuery(String sql, String[] returnAliases, Class[] returnClasses);

これが hibernate3 になって createSQLQuery の引数と戻り値が変更された。

org.hibernate.Session
    public SQLQuery createSQLQuery(String queryString) throws HibernateException;

hibernate2 の createSQLQuery の引数は、新設された SQLQuery クラスを使用する方法へと変更になった。

org.hibernate.SQLQuery
    public SQLQuery addEntity(String entityName);
    public SQLQuery addEntity(String alias, String entityName);
    public SQLQuery addEntity(String alias, String entityName, LockMode lockMode);
    public SQLQuery addEntity(Class entityClass);
    public SQLQuery addEntity(String alias, Class entityClass);
    public SQLQuery addEntity(String alias, Class entityClass, LockMode lockMode);

使用方法の例としては以下のようになる。
hibernate2

    Query query = getSession().createSQLQuery(sql, "abc", Abc.class);

hibernate3

    SQLQuery query = getSession().createSQLQuery(sql);
    query.addEntity("abc", Abc.class);

トラックバックの受信処理で文字化け

現象

request の setCharacterEncoding を設定しているのに文字化けしてしまう。

原因

setCharacterEncoding より前に getParameter を行っていた為に文字エンコーディングが確定してしまい、設定した文字エンコーディングが意味を成していなかった。

対応

トラックバックの(過渡期の)仕様として charset パラメータにて文字エンコーディングを指定するというものがあるが、Servlet 的には getParameter (正確には getReader)を呼んだ時点でエンコーディングが確定してしまう。手動でエンコーディングするしかないか。

Struts 1.2.8で使用されているCommons Validator 1.1.4のバグ

現象

Struts 1.2.8のURLバリデーションで正しいURLがエラーになってしまう。

原因

Struts 1.2.8で使用されているCommons Validator 1.1.4のURLバリデータ(正確には UrlValidator クラス)のバグ。

対応

UrlValidator だけ Commons Validator 1.2 のクラスと置き換えることで対応


validatorのソースを読んでやっと問題が分かりました。もっと早くググっとけば・・・

Hibernate で LazyInitializationException

現象

sessionは閉じていないのに、遅延初期化のオブジェクトを呼び出すと LazyInitializationException が発生する。

原因

遅延初期化のオブジェクトを呼び出す前に、親となるオブジェクトを evict していた為に発生していた。

対応

evict しないことで対応。


考えれてみれば納得なのだが、しばらく気がつかず悩んでしまった。盲目的に evict しちゃダメですね。

Purple Cowとは

常識破りで、今までにない製品のこと。
セス・ゴーディングの著書「「紫の牛」を売れ!」で語られている。amazon:「紫の牛」を売れ!
マーケティングの4大要素である4つの「P」に新たに加わる「P」であるとのこと。

  • Product(製品)
  • Price(価格)
  • Place(流通)
  • Promotion(宣伝)

AOPとDAOの適材適所

ゆーたんのつぶやき」の岩上由高さんからトラックバックをいただきました。
初めていただいたトラックバックで(エントリへのトラックバックではなく、はてな自動トラックバックかな?)気づくのが遅れてしまいました。前回のよっぱらいの書いた失礼なエントリに、本当にありがとうございます。
2006-01-30
岩上由高さんもおっしゃられているように、用語に対する定義のニュアンスの違いは、私もどうしようもなく存在するものと思っています。ですので今回は「振る舞い」とか「横断的関心事」 とかは極力なくして説明していきたいと思います。
そもそもDAOパターンとAOPは全く性質の異なるものなので、比較すること自体愚かではあると思いますが、やってみたいと思います。

まずDAOパターンです。DAOパターンは一言で例えるならば「環境変数」です。
システムの動作する環境にもいろいろあるわけで、データベースがある環境もあれば、ない環境もあるわけです。どの環境でも同じようにシステムを動作させるために、環境に応じてデータベースDAOやファイルDAO等を切り替える、言わば「環境変数」の値を書き換えることで対応します。 こういった環境の違いを吸収するためのテクニックがDAOパターンです。
そしてAOPでも近いことが可能です。
AOPを例えるならば、全ての環境で同じ環境変数の値を使用する「固定の環境変数」です。
これは表面上は、なぜ動作するのかわからないでしょうが、裏で変数の値を横取りして入れ替えることで実現しているわけです。・・・ちょっと違和感がないですか?
他にも例を挙げてみます。
ブログのシステムの場合、エントリが投稿されるたびに、エントリをキャッシュするために何かに追加していくことになります。
これをAOPで実現するには、表面上はリストにキャッシュしつつ、裏でキャッシュ内容を永続化する処理となります。しかし、このやり方では表面上は膨大な数のエントリを全てキャッシュしなくてはいけないので、いずれ破綻します。
逃げの方法として、表面上はリストにキャッシュしているように見せながら、その処理をスキップして永続化していく方法ですが、実際はリストにはキャッシュされていないので、エントリの取得処理を含む、全てのリストへのアクセスをAOPで監視する必要があり、これまたそのうち破綻するでしょう。
これがDAOパターンであれば表面上の処理は(表面上の処理しかありませんが)すべてDAOを通してアクセスすることとなるので、環境に応じて切り替えればいいだけの話となります。
結局、AOPはもっと別のところ、(良い例が見つかりませんが)例えば「このシステムでは環境変数を読むのにスイッチを切り替えて、読んだ後に戻してあげる必要がある」処理などに使いどころがあります。そしてこれを「横断的関心事」と呼ぶわけですよね。
やる気さえあれば1つのシステムを1つの空のメソッドだけで、後は全部AOPで実現することだって可能なわけで、何でも出来てしまうわけですが、誰もやりたくないですよね?
AOPとDAO、それぞれの適材適所を簡単にですが説明してみました。