Jakarta ee JavaEE7:调用EJB方法+;交易自";非托管;上下文 请考虑以下情况:

Jakarta ee JavaEE7:调用EJB方法+;交易自";非托管;上下文 请考虑以下情况:,jakarta-ee,managed-bean,java-ee-7,Jakarta Ee,Managed Bean,Java Ee 7,1) 一个单例SchedulerService,除其他功能外,它管理/创建一组JobQueue @Startup @Singleton public class SchedulerService { @Inject private Instance<JobQueue> jobQueueInstance; ... public JobQueue addQueue(String name) { JobQueue q = job

1) 一个单例SchedulerService,除其他功能外,它管理/创建一组
JobQueue

@Startup
@Singleton
public class SchedulerService
{
    @Inject
    private Instance<JobQueue> jobQueueInstance;

    ...

    public JobQueue addQueue(String name)
    {
         JobQueue q = jobQueueInstance.get();
         ....
         return q;
    }
}
一切正常,entityManager被正确地@Injected,当从其他托管bean调用
addJob()
deleteJob()
时,实体被正确地持久化/删除

现在,对于实际的作业执行,我使用的是Cron4j,它不支持CDI。 它启动新线程并在该线程中运行实际作业。 当作业结束时,它通过
tasksuccessed
/
taskFailed
方法通知我的作业队列(侦听作业终止事件的人)

由于这些
taskseceded
/
taskFailed
方法是从作业线程(不是“容器管理的”)调用的,因此我可以理解得到以下异常:

4:46:27,032 ERROR [cob.scheduler.service.JobQueue] (cron4j::scheduler[DEFAULT]::task[442]) Job xxx failed: javax.persistence.TransactionRequiredException: WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context)
    at org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:869) [wildfly-jpa-9.0.0.Alpha1.jar:9.0.0.Alpha1]
    at org.jboss.as.jpa.container.AbstractEntityManager.merge(AbstractEntityManager.java:567) [wildfly-jpa-9.0.0.Alpha1.jar:9.0.0.Alpha1]
    at cob.scheduler.service.JobQueue.deleteJob(JobQueue.java:287) [classes:]
    at cob.scheduler.service.JobQueue.deleteAndAdvance(JobQueue.java:241) [classes:]
    at cob.scheduler.service.JobQueue.taskSucceeded(JobQueue.java:226) [classes:]
    at it.sauronsoftware.cron4j.Scheduler.notifyTaskSucceeded(Scheduler.java:724) [classes:]
    at it.sauronsoftware.cron4j.TaskExecutor$Runner.run(TaskExecutor.java:500) [classes:]
    at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_45]
我想知道什么是继续进行的好方法。基本上,我需要以某种方式“回到EE容器”,即从EE领域之外调用容器管理的方法

我已经读过有关
ManagedExecutorService
的内容,但我不确定这是否适用或如何使用它

我还尝试
@注入私有JobQueue self
并调用
self.deleteJob()
,而不仅仅是
this.deleteJob()
,但这会在部署时生成以下异常:

org.jboss.weld.exceptions.DeploymentException: WELD-001443: Pseudo scoped bean has circular dependencies. Dependency path: 
  - Managed Bean [class cob.scheduler.service.JobQueue] with qualifiers [@Any @Default],
  - [BackedAnnotatedField] @Inject private cob.scheduler.service.JobQueue.self,
  - Managed Bean [class cob.scheduler.service.JobQueue] with qualifiers [@Any @Default]
    at org.jboss.weld.bootstrap.Validator.reallyValidatePseudoScopedBean(Validator.java:904)
    at org.jboss.weld.bootstrap.Validator.validatePseudoScopedInjectionPoint(Validator.java:946)
    at org.jboss.weld.bootstrap.Validator.reallyValidatePseudoScopedBean(Validator.java:913)
    at org.jboss.weld.bootstrap.Validator.validatePseudoScopedBean(Validator.java:890)
    at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:148)
    at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:165)
    at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:529)
    at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
    at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0_45]
    ... 3 more
注意:除了“资源本地”事务管理,我的一切都正常工作。我想把它转换成JTA很容易,但唉


任何指点都将不胜感激。

结果证明解决方案并不那么难。我们每天都在学习。是的

  • @将
    SchedulerService
    注入
    JobQueue
    。这就产生了一种循环依赖性,但很好
  • SchedulerService
    中,创建一个代理方法
    deleteJob(JobQueue jq,Job j)
    。所有这些都是调用
    jq.deleteJob(j)
  • 从“非托管”事件回调调用代理
    schedulerService.deleteJob(this,j)
    ,而不是
    this.deleteJob(j)
    。通过检查@inspected代理,JavaEE再次发挥作用,为我们和所有其他奇妙的魔力创造了交易
  • 利润
    您可以避免使用cron4J,在一个ejb中的方法上使用
    @Schedule
    ,也可以使用编程计时器以编程方式创建计划任务。在任何一种情况下,他们都将使用CMT,您不必跳过所有这些障碍。@NBW感谢我知道
    @Schedule
    和其他替代方案,但我需要最大的灵活性/可配置性来模拟一些遗留行为。
    org.jboss.weld.exceptions.DeploymentException: WELD-001443: Pseudo scoped bean has circular dependencies. Dependency path: 
      - Managed Bean [class cob.scheduler.service.JobQueue] with qualifiers [@Any @Default],
      - [BackedAnnotatedField] @Inject private cob.scheduler.service.JobQueue.self,
      - Managed Bean [class cob.scheduler.service.JobQueue] with qualifiers [@Any @Default]
        at org.jboss.weld.bootstrap.Validator.reallyValidatePseudoScopedBean(Validator.java:904)
        at org.jboss.weld.bootstrap.Validator.validatePseudoScopedInjectionPoint(Validator.java:946)
        at org.jboss.weld.bootstrap.Validator.reallyValidatePseudoScopedBean(Validator.java:913)
        at org.jboss.weld.bootstrap.Validator.validatePseudoScopedBean(Validator.java:890)
        at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:148)
        at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:165)
        at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:529)
        at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
        at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
        at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60)
        at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0_45]
        ... 3 more