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
?举个小例子就好了!找到这个