久しぶりにJPAネタです。
Java EE 7のJPA 2.1からEntity ListenerでCDIが利用できるようになりました。
EclipseLinkの例だと@EJBで書かれてます。
EclipseLink/Release/2.5/JPA21 - Eclipsepedia
この例だと、うーんロガーをわざわざEJBでかぁ…(^^;という感じが個人的にしたので、前にきしださんが書いていたプロデューサー使う方法でやってみました。d.hatena.ne.jp
LoggerProducerはそのまんまお借りして
@Named@Dependentpublicclass LoggerPoducer { @Producespublic Logger getLogger(InjectionPoint ip){ return Logger.getLogger(ip.getMember().getDeclaringClass().getName()); } }
EclipseLinkの例にあったLoggerEntityLisetenerの@EJBを@Injectへ
publicclass LoggerEntityListener { @Inject//ProducerでInjectされるprivate Logger logger; @PrePersistpublicvoid prePersist(Object object) { logger.info("prePersist"); } @PostPersistpublicvoid postPersist(Object object){ logger.info("postPersist"); } @PreDestroypublicvoid preDestroy(){ logger.info("preDestroy"); } @PostConstructpublicvoid postConstruct(){ logger.info("postConstruct"); } }
そして、対象のEntityクラスに@EntityListenersでLoggerEntityListenerを指定しました。
@Entity@EntityListeners({LoggerEntityListener.class})
EclipseLinkは2.5.2、APサーバはGlassFish 4.1で試したのですが…なぜかloggerがnullで上手くインジェクトされませんでした。
色々調べていたら以下に辿り着き
上記に以下リンクがありますが、GF4.1の問題っぽい?現象としてはこれと全く同じでした。
[GLASSFISH-21195] CDI Injection in Entity Listener - NullPointerException - Java.net JIRA
さらに読むとEclipseLink2.5.2の問題じゃないかみたいな。
Bug 438105 – Logic bug in EntityListenerInjectionManagerImpl
で、最終的には、最新のPayaraにはEclipseLink2.6が入って、それで動くよとのこと。
ということで、初めてPayaraをダウンロードしました。中はホント完全にGlassFishなんですね(^^;
Pre-Release Builds
利用したのは「Payara-web 4.1.153 (Web Profile)」です。
そして実行すると…動きました!
GlassFishをPayaraに変えるのは全く手間がなさそうです。普通に動くし、今回のようにPayaraのほうが対応が早いケースがあるのを知ると、ちょっと真面目にPayara追っていかないとなーと。
前から既に追っているはすぬまさんのブログで勉強していかねば!
既にめっちゃPayaraについて書かれている(*´Д`)さすがすぎる
はすぬまさんのブログで「Payara」のタグがついている記事の検索結果
Programming Studio - 検索結果
CDI Entity Listenersについての日本語参考情報は以下。