LoginSignup
0
0

「org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped」が発生する原因

Posted at

はじめに

タイトルにあるエラーが発生したときの調査結果を残しておく。載せてるコードは実際のものではなく、エラーを発生させるための最小限のコード。

環境

  • Java8
  • JavaEE7(参照実装Payara4.1)

エラーを発生させるプログラム

以下はEntityManagerをInjectさせるために定義

EntityManagerProducer.java
@ApplicationScoped
public class EntityManagerProducer {

    @PersistenceContext
    private EntityManager entityManager;

    @Produces
    @RequestScoped
    public EntityManager getEntityManager() {
        return entityManager;
    }
}
User.java
@Entity
@Table(name = "user")
public class User {
    @Id
    private Integer id;

    public Integer getId(){
        return this.id;
    }
}
UserController.java
@ApplicationScoped
@Path("users")
public class UserController {
    @Inject
    private EntityManager entityManager;
    
    @GET
    public Response list(){
        IntStream.of(2,1,3).parallel().forEach(l -> {
            entityManager.createQuery("SELECT u FROM User u WHERE u.id = :id", User.class)
                .setParameter("id", l)
                .getResultList()
                .stream()
                .findAny();
        });
        return Response.ok().build();
    }
}

対応方法

その1)parallel()を使わない

UserController.java
@ApplicationScoped
@Path("users")
public class UserController {
    @Inject
    private EntityManager entityManager;
    
    @GET
    public Response list(){
        IntStream.of(2,1,3).forEach(l -> {
            entityManager.createQuery("SELECT u FROM User u WHERE u.id = :id", User.class)
                .setParameter("id", l)
                .getResultList()
                .stream()
                .findAny();
        });
        return Response.ok().build();
    }
}

その2)EntityManagerのDIにPersistenceContextアノテーションを利用する

UserController.java
@ApplicationScoped
@Path("users")
public class UserController {
    @PersistenceContext
    private EntityManager entityManager;
    
    @GET
    public Response list(){
        IntStream.of(2,1,3).parallel().forEach(l -> {
            entityManager.createQuery("SELECT u FROM User u WHERE u.id = :id", User.class)
                .setParameter("id", l)
                .getResultList()
                .stream()
                .findAny();
        });
        return Response.ok().build();
    }
}

おわりに

原因と対応方法はわかったけど、@PersistenceContext@Injectのライフサイクルなど詳細な仕組みの違いなどはよく理解していない。ただ一つ言えることは、I/Oが発生する処理ではparallelを利用しない方がいい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0