@Remote EJB使用@RequestScoped CDI bean

时间:2015-11-20 12:26:25

标签: java java-ee cdi wildfly

我有一个应用程序,它有一个@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会话,就再次执行该代码。如果在调用getFramworkResourceManager之前再次调用resolveRights,则无法更改。

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

如果我使用直接JNDI查找或@EJB注入,则无关紧要。报告的返回实例(toString())为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);
}

resolveUser:[{1}}

的Sysout

org.hibernate.jpa.internal.EntityManagerImpl@379e882b || true:[{1}}

的Sysout

编辑20.11.2015 13:43 :持久性单位属于resolveRights类型。此外,所有org.hibernate.jpa.internal.EntityManagerImpl@379e882b || false bean都会受到影响。仅为第一次EJB调用调用RESOURCE_LOCAL@ResourceScoped。每次后续调用都使用资源范围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)。

2 个答案:

答案 0 :(得分:1)

当使用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();
    }
}

答案 1 :(得分:0)

此有线行为的修正已合并到WELD存储库中: