昔の日記で、EclipseLinkとSpringを使ったLazy Loadingの設定方法を紹介しました。
本日、EclipseLink-2.0.0がさりげなくリリースされているのを発見。早速乗り換えてみたところ…
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long jp.root42.r42fw.model.entity.AbstractEntity._persistence_set(AbstractEntity.java) jp.co.example.auth.model.entity.LoginUserAccount._persistence_set(LoginUserAccount.java) org.eclipse.persistence.internal.descriptors.PersistenceObjectAttributeAccessor.setAttributeValueInObject(PersistenceObjectAttributeAccessor.java:46) org.eclipse.persistence.mappings.DatabaseMapping.setAttributeValueInObject(DatabaseMapping.java:1367) org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.buildCloneFromRow(AbstractDirectMapping.java:1203) ...
謎のエラーが発生orz
バイトコードエンハンスされた部分で起きているエラーなので、何が原因なのかソースを読むこともできず。さて困った。
回避手段
で、EclipseLinkのソースを読んだりと散々調べまわった挙句、Springの設定ファイルで以下のように設定すると、エラーを回避できることが判明。
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter" /> </property> <property name="jpaPropertyMap"> <map> <entry key="eclipselink.weaving" value="true" /> <entry key="eclipselink.weaving.internal" value="false" /> ←ココに注目!! </map> </property> </bean>
「eclipselink.weaving.internal="true"」が原因でした。(デフォルト値はtrue)
"eclipselink.weaving.internal"って何?
"eclipselink.weaving.internal"って何なんでしょう。
ココの投稿によると、
The easiest workaround is to turn off internal weaving. This will still allow LAZY and change tracking, it only disables some minor optimizations. 最も簡単な手段は、internal weavingをoffにすることだ。 こう設定してもLAZYローディングやchange trackingは引き続き有効であり、ただ単にいくつかの最適化をoffにするだけだ。
ただの最適化かよ…(#^ω^)ビキビキ
2010-05-22追記
EclipseLink-2.0.2でも未修正のようです。
再現するソースを書いてバグレポート送ろうかな。