Inheritance EJB抽象方法的本地调用是否打开新事务?

Inheritance EJB抽象方法的本地调用是否打开新事务?,inheritance,jakarta-ee,transactions,ejb,Inheritance,Jakarta Ee,Transactions,Ejb,假设类的结构如下: 一种Filereader,它为文件找到匹配的导入程序并调用importer.import方法 此方法调用用REQUIRES\u NEW注释的抽象方法importSpecific 从容器的角度来看,本地调用不会打开新事务,但从继承的角度来看,我不确定 importSpecific是否调用ImporterBase.import创建新事务,为什么会这样 类文件读取器: @Singleton(name = "FileReader") public class FileReader e

假设类的结构如下:

一种
Filereader
,它为文件找到匹配的导入程序并调用
importer.import
方法

此方法调用用REQUIRES\u NEW注释的抽象方法
importSpecific

从容器的角度来看,本地调用不会打开新事务,但从继承的角度来看,我不确定

importSpecific
是否调用
ImporterBase.import
创建新事务,为什么会这样

类文件读取器:

@Singleton(name = "FileReader")
public class FileReader extends Traceable {

    /*@Inject
      @Any
      public Instance<Importer> importers;*/

    @EJB
    ExampleImporter importer;

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void listenToFileAvailableEvent(@Observes FileAvailable event) throws InterruptedException {        
        for (final String filename : event.getFilenames()) {            
            readFile(filename);
        }
    }

    public void readFile(String filenameWithPath) {
        //[...]-> Extract FileMetadata and find correct importer
        importer.import(dateiMeta);
    }
}
类ImporterBase:

public abstract class ImporterBase implements Importer {
   @Resource
   private SessionContext ctx;

   @Override
   public void import(FileMetaData dateiMeta) throws Exception {           
       try {           
          ctx.getBusinessObject(Importer.class).importSpecific(dateiMeta);//This causes the error
       } catch (Exception ex) {            
           //[...] Log Error
           throw ex;
       }        
   }

   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   public abstract void importSpecific(FileMetaData dateiMeta) throws   Exception;

}
类示例进口商:

@Local
public interface Importer {
    void import(FileMetaData dateiMeta) throws Exception;
    void importSpecific(FileMetaData dateiMeta) throws Exception;
}
@Stateless
public class ExampleImporter extends ImporterBase {

    @Override
    public void importSpecific(FileMetaData dateiMeta) throws Exception {
        //Import from file
    }   
}

否,
importSpecific
方法调用的时间(以及方式)
import
从不打开新事务;因为(正如您所说)对容器的调用始终是本地调用

但是,根据,注释
@TransactionAttribute
可以继承。。。所以

为了使这种配置发挥作用,您必须:

1) 在业务界面上声明
importSpecific
方法,即
Importer
界面

2) 将
导入器
接口表示为本地接口

3) 在
FileReader
Singleton中,使用
@EJB
注释获取导入器Bean的代理。如果使用CDI注释(如@Inject),容器将注入CDI对象,而不是EJB代理!(小心这个)

4) 将您的
ImporterBase
代码更改为:

public abstract class ImporterBase implements Importer {
    @Resource
    private SessionContext ejbCtxt;

    @Override
    public void import(FileMetaData dateiMeta) throws Exception {
        Importer proxy0;    
        try {           
            proxy0 = this.ejbCtxt.getBusinessObject(Importer.class);
            proxy0.importSpecific(dateiMeta);

        } catch (Exception ex) {            
            //[...] Log Error
            throw ex;
        }        
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public abstract void importSpecific(FileMetaData dateiMeta) throws Exception;

}
5) 将您的
示例导入器
更改如下:

@Stateless
@Local(Importer.class)
public class ExampleImporter extends ImportBase {
...
}

如果您真的需要在Singleton类中使用CDIBeans而不是EJB代理,那么您将需要使用
@Transactional
CDI注释来代替。。。您的代码也应该进行重构。

谢谢您的回复。我尝试了您的解决方案,但始终得到一个WFLYEJB051:找不到EJB的视图[…]导入器[…]示例导入器。我在界面上添加了“@Local”注释。我需要查看您的代码以帮助您更多。。。你能用修改过的代码更新你的问题吗?很抱歉回答晚了。。。我只是尝试一下你的代码,但是你需要做2个修改才能工作:一个,用
@Local(Importer.class)
注释
ExampleImporter
类。。。第二,在
FileReader
Singleton,将您的EJB声明为
Importer
而不是
ExampleImporter
。。。示例:
@EJB私有导入器这很有效。。我刚试过谢谢你的回复。我实际上有10个进口商,所以不仅仅是
示例进口商
。因此,我使用了
@Inject@Any Instance importers
。我如何才能获得一个列表或与direct
@EJB
类似的东西?我必须编写一个
@Producer
?举个小例子就好了!找到这个