繁体   English   中英

使用@RequestScoped CDI bean的@Remote EJB

[英]@Remote EJB which uses @RequestScoped CDI bean

我有一个具有@Remote @Singleton EJB的应用程序,该应用程序注入了由CDI生成的@RequestScoped实体管理器。 同一服务器(wildfly 9)/ JVM上的另一个应用程序将使用此EJB从实体管理器获取结果。

EJB的第一次调用将返回预期的结果。 它产生实体管理器,获取数据,并在调用返回时再次处置实体管理器。 由于关闭了实体管理器,因此对该EJB的每次后续调用都将引发错误。 没有为新的实体经理生产/处置的产品。

这是预期的行为吗? 我的代码中有错误吗?


IFrameworkResourceManager framework = _applicationContext.getFrameworkResourceManager();
final User resolvedUser = framework.resolveUser(username, domain);
// ...
final Rights resolvedRights = framework.resolveRights(resolvedUser.getGuid(), applicationId);
// ...

这段代码在CDI生产者中执行,一旦为用户创建了新的http会话,该代码就会再次执行。 如果在调用resolveRights之前再次调用getFramworkResourceManager ,则没有任何改变。


public IFrameworkResourceManager getFrameworkResourceManager() {
    return IFrameworkResourceManager frm = (IFrameworkResourceManager) ctx
        .lookup("java:global/WebFramework/WebFrameworkImpl!my.package.IWebFramework");
}

我使用直接JNDI查找还是@EJB注入都没关系。 返回的实例被报告Proxy for remote EJB StatelessEJBLocator for "/WebFramework/WebFrameworkImpl", view is interface my.package.IWebFramework, affinity is NoneProxy for remote EJB StatelessEJBLocator for "/WebFramework/WebFrameworkImpl", view is interface my.package.IWebFramework, affinity is NonetoString()Proxy for remote EJB StatelessEJBLocator for "/WebFramework/WebFrameworkImpl", view is interface my.package.IWebFramework, affinity is None


@LocalBean
@Singleton
public class WebFrameworkImpl implements IWebFramework, Serializable {
    @Inject
    private EntityManager _entityManager;

    @Override
    public User resolveUser(String username, String domain) {
        System.out.println(_entityManager + " || " + _entityManager.isOpen());
        // execute query using QueryDSL and the injected entityManager
    }

    @Override
    public Rights resolveRights(String guidUser, int applicationId) {
        System.out.println(_entityManager + " || " + _entityManager.isOpen());
        // execute query using QueryDSL and the injected entityManager
    }
}

@Remote
public interface IWebFramework extends IFrameworkResourceManager {
    // some methods...
}

public interface IFrameworkResourceManager {
    public User resolveUser(String username, String domain);
    public Rights resolveRights(String guidUser, int applicationId);
}

解决用户的resolveUserorg.hibernate.jpa.internal.EntityManagerImpl@379e882b || true org.hibernate.jpa.internal.EntityManagerImpl@379e882b || true

Sysout的resolveRightsorg.hibernate.jpa.internal.EntityManagerImpl@379e882b || false org.hibernate.jpa.internal.EntityManagerImpl@379e882b || false


编辑20.11.2015 13:43 :持久性单元的类型为RESOURCE_LOCAL 此外,所有@ResourceScoped Bean均会受到影响。 @PostConstruct@PreDestroy仅在第一次EJB调用时被调用。 每次后续调用都使用资源范围Bean的先前实例,该实例不正确。

编辑20.11.2015 13:55 :如果从提供EJB的同一应用程序中调用EJB,一切都会按预期工作。 仅当从其他应用程序进行调用时,才会出现此行为。

编辑20.11.2015 15 :24:JBoss AS 7.1.3.Final,Wildfly 9.0.0.Final和Wildfly 10.0.0.CR4均生效。 但是根据CDI规范(1.0至1.2)第6.7.4章,这应该可行。 我已经填写了一个错误报告(WFLY-5716)。

使用RESOURCE_LOCAL ,应从EntityManagerFacgtory创建您的EntityManager并自行处理,例如:

private EntityManagerFactory factory = Persistence.createEntityManagerFactory("unit-name");

public void someMethod(){

    EntityManager em = emf.createEntityManager();
    EntityTransaction tx = null;
    try {
      tx = em.getTransaction();
      tx.begin();

      // do some work

      tx.commit();
    }
    catch (RuntimeException e) {
      if ( tx != null && tx.isActive() )
        tx.rollback();
      throw e; // or display error message
    }
    finally {
      em.close();
    }
}

针对此有线行为的错误修正已在WELD存储库中合并:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM