hibernate3ではまった!

3.0.5から現時点の最新の3.2.5.gaへバージョンアップする際に、はまりました。バージョンアップにあわせてxdoclet表記からhibernate annotation表記に書き換えを行っていたのですが、buildSessionFactoryを実行する際に「org.hibernate.MappingException: Could not determine type for: 略」が発生します。なんじゃこりゃーと思ったのですが、解決しました。

hibernateアノテーションを使った時の動き

いつからそうなったのかは知りませんが、プロパティにアノテーションをつけていない場合は、勝手にhibernateが解釈するみたいです。めちゃ迷惑だ。このせいではまりました。例えば以下のようなクラスがあったとします。

@Entity
public class AAA {

    @Id
    private String id;

    @Column
    private String hoge;

    @Column
    private String hage;

    private List someList = new ArrayList();

    // getter setterは略

someListにはアノテーションを書いていないので、僕の意図としては、これはロジックに使用するListであって、one-to-manyとかのListではないよ、ということ。しかしhibernateはこのsomeListプロパティを勝手に解釈して、自分の管理対象に置こうとするみたい。


hibernateのドキュメントによると以下のような振る舞いになるよ、と書いています。

2.2.2.4. Non-annotated property defaults

If a property is not annotated, the following rules apply:

* If the property is of a single type, it is mapped as @Basic
* Otherwise, if the type of the property is annotated as @Embeddable, it is mapped as @Embedded
* Otherwise, if the type of the property is Serializable, it is mapped as @Basic in a column holding the object in its serialized version
* Otherwise, if the type of the property is java.sql.Clob or java.sql.Blob, it is mapped as @Lob with the appropriate LobType

どうするか

ということで、これは違うと明記し、hibernateに分からせる必要があるのです。
それが、@Transientタグ。「transient」の意味は「はかない」とかいった意味です。つまり「永続」の反対語ってことですね。@Transientタグをつけて明記すればこの問題回避できるようになりました。