読者です 読者をやめる 読者になる 読者になる

Challenge Java EE !

Java EEを中心に趣味や仕事における開発メモを書いています。

Injectで起きた循環依存(circular dependencies)

EJB CDI Inject

一緒に開発している後輩から「こんなエラーが」と見せてもらったら

org.jboss.weld.exceptions.DeploymentException: WELD-001443 Pseudo scoped bean has circular dependencies. Dependency path [Session bean [class jp.co.hogehoge.ejb.OpportunityLogic with qualifiers [@Any @Default]; local interfaces are [OpportunityLogic], Session bean [class jp.co.hogehoge.ejb.CustomerLogic with qualifiers [@Any @Default]; local interfaces are [CustomerLogic], Session bean [class jp.co.hogehoge.ejb.OpportunityLogic with qualifiers [@Any @Default]; local interfaces are [OpportunityLogic]]

と出てました。話を聞いてみると、あれ、これ今までよくなかったな…とも思ったり(^^;
(環境はJava EE6,GlassFish3.1.2.2)

すごいざっくりした例にすると以下のようなコードです。

例えば商談情報に関する処理をするEJBと顧客情報に関する処理をするEJBがあって、以下のように互いでInjectしてしまったような場合です。(実際以下お試しコードで出たエラーが上記)

package jp.co.hogehoge.ejb;

import javax.ejb.Stateless;
import javax.inject.Inject;

@Stateless
public class CustomerLogic {

    @Inject
    private OpportunityLogic oppLogic;
    
    public String findCustomer(){
        //本来DBから顧客データを取得するような処理とか
        return "顧客情報だよ";
    }
}
package jp.co.hogehoge.ejb;

import javax.ejb.Stateless;
import javax.inject.Inject;

@Stateless
public class OpportunityLogic {

    @Inject
    private CustomerLogic customerLogic;
    
    public String findOpportunity(){
        //本来DBから商談データを取得するような処理とか
        return "商談情報だよ";
    }
}

商談の処理の中で顧客情報を取ったり、顧客の処理の中で商談情報を取ったり、わりとありがちな…(^^;

「circular dependencies」でググったら英語でたくさん情報出てきたので、結構ある話なんだなぁと。

というか、javax.inject.InjectクラスのJavaDocにも説明があった(^^;
http://docs.oracle.com/javaee/6/api/javax/inject/Inject.html

対策としては以下StackOverflowで

CDI injection loop
http://stackoverflow.com/questions/15300338/cdi-injection-loop

  • 1つのクラスにしてしまう
  • もう1つ別のクラスを作って、各々それをInjectする

という感じに書いてありました。スコープ変えてもいけるよ的な情報もありましたが、イマイチよくわからず…(^^;

にほんブログ村 IT技術ブログへ
にほんブログ村
にほんブログ村 IT技術ブログ Javaへ
にほんブログ村