Hibernate Annotations を使い始めるときにハマったこと
Hibernateは、オープンソースのORマッピングフレームワークです。
http://www.hibernate.org/
Hibernate Annotationsを使えば、あのくだらん 〜〜.hbm.xml を書かなくてよいとの事で、結構嬉しそうなので使ってみます。
本家のドキュメントと、Kishida's SITE 〜 Java入門講座 の Hibernate Annotationsをちょっぴり参考にしました。
最近は色んなフレームワークがconvention over configurationで楽にできるのでよいですね。struts2+zero configuration+codebehindとか。
そんなわけで、このエントリでは、 Hibernateは 2 の頃にちょろっと触っただけの私が、Hibernate Annotation をセットアップするまでにハマったことを書きます。
hibernate.cfg.xml をどこに置いて良いのかわからなかった
出た例外 : "org.hibernate.HibernateException: Hibernate Dialect must be explicitly set"
- classpathのルートに置けばよいです。↓とのコンボで一瞬迷いました
AnnotationConfiguration#configure() を呼ぶのを忘れた
出た例外 : "org.hibernate.HibernateException: Hibernate Dialect must be explicitly set"
出た警告 : "WARN UserSuppliedConnectionProvider:23 - No connection properties specified - the user must supply JDBC connections"
- 本家のドキュメント をコピペしたらおもいっきり抜けてました。
- AnnotationConfiguration でも、 configureメソッドが必要みたいです。
package-info.javaがないという警告
出た警告 : WARN AnnotationBinder:217 - Package not found or wo package-info.java: パッケージ名
とりあえず、必須ではありません。
対象パッケージにpackage-info.class を置いておくと、この警告が出なくなりました。
初めて知ったんですが、パッケージには package-info.java を置くと javadocにも反映されるそうです。
package-info.java には、ふつう パッケージ名の宣言のみを書いておきます。
間違えて AnnotationConfiguration#addClass を呼んだ
出た例外 : "org.hibernate.MappingNotFoundException: resource: クラス名.hbm.xml not found"
- アノテートされたクラスの設定をJavaのソースに書くときは、addClassではなく addAnnotatedClass を呼びましょう。
間違えて @org.hibernate.annotations.Entity アノテーション を使った
出た例外 : "org.hibernate.MappingException: Unknown entity: クラス名のQN"
Session#load でこの例外が出ました。
@javax.persistence.Entity を使えとのこと。同様に @org.hibernate.annotations.Table というアノテーションもあるので、間違えそうです。
ソースはHibernate Annotations FAQ。
この場合、Criteria#list の結果が空になり、例外も出ないので分かりにくいです。 登録していないエンティティに対しては、例外くらい出してほしいものですが…
getter/setter を使わないとハマる
これは Annotations とは関係ないけれど、マッピング対象のクラスにフィールドを使うと まともに動かない。
(フィールドに直接アクセスすると lazy initialization が効かないからだと推測する。)
(08/10/30追記) デフォルト(引数なし)コンストラクタがないと例外
(題名の通り) 対象クラスにデフォルトコンストラクタがないと例外が出ます.
引数を持たないコンストラクタを追加すれば例外は発生しません.
org.hibernate.HibernateException: Javassist Enhancement failed: tables.Entry at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.getProxy(JavassistLazyInitializer.java:142) at org.hibernate.proxy.pojo.javassist.JavassistProxyFactory.getProxy(JavassistProxyFactory.java:72) at org.hibernate.tuple.entity.AbstractEntityTuplizer.createProxy(AbstractEntityTuplizer.java:402) at org.hibernate.persister.entity.AbstractEntityPersister.createProxy(AbstractEntityPersister.java:3483) at org.hibernate.event.def.DefaultLoadEventListener.createProxyIfNecessary(DefaultLoadEventListener.java:298) at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:219) at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126) at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905) at org.hibernate.impl.SessionImpl.load(SessionImpl.java:822) at org.hibernate.impl.SessionImpl.load(SessionImpl.java:815) at test.db.EntryTest1.main(EntryTest1.java:13) Caused by: java.lang.InstantiationException: tables.Entry_$$_javassist_0 at java.lang.Class.newInstance0(Class.java:340) at java.lang.Class.newInstance(Class.java:308) at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.getProxy(JavassistLazyInitializer.java:139) ... 10 more Exception in thread "main" org.hibernate.HibernateException: Javassist Enhancement failed: tables.Entry at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.getProxy(JavassistLazyInitializer.java:142) at org.hibernate.proxy.pojo.javassist.JavassistProxyFactory.getProxy(JavassistProxyFactory.java:72) at org.hibernate.tuple.entity.AbstractEntityTuplizer.createProxy(AbstractEntityTuplizer.java:402) at org.hibernate.persister.entity.AbstractEntityPersister.createProxy(AbstractEntityPersister.java:3483) at org.hibernate.event.def.DefaultLoadEventListener.createProxyIfNecessary(DefaultLoadEventListener.java:298) at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:219) at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126) at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905) at org.hibernate.impl.SessionImpl.load(SessionImpl.java:822) at org.hibernate.impl.SessionImpl.load(SessionImpl.java:815) at test.db.EntryTest1.main(EntryTest1.java:13) Caused by: java.lang.InstantiationException: tables.Entry_$$_javassist_0 at java.lang.Class.newInstance0(Class.java:340) at java.lang.Class.newInstance(Class.java:308) at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.getProxy(JavassistLazyInitializer.java:139) ... 10 more