2017-02-07 11 views
1

Предполагая следующую конструкцию классов:Локальный вызов абстрактного метода EJB открывает новую транзакцию?

Filereader, что находит соответствующий импортер для файла и вызывает метод Importer.import.

Этот метод вызывает абстрактный метод , который аннотируется REQUIRES_NEW.

С точки зрения контейнера локальный вызов не открывает новую транзакцию, но из перспективы наследования я не уверен.

Совершает ли звонок в ImporterBase.import создать новую транзакцию или нет, и почему это так?

Класс FileReader:

@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); 
    } 
} 

импортер Интерфейс:

@Local 
public interface Importer { 
    void import(FileMetaData dateiMeta) throws Exception; 
    void importSpecific(FileMetaData dateiMeta) throws Exception; 
} 

Класс 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; 

} 

Класс ExampleImporter:

@Stateless 
public class ExampleImporter extends ImporterBase { 

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

ответ

0

No, Когда (и как) вызывается по вашему методу import никогда не открывает новую транзакцию; потому что (как вы говорите), чтобы контейнер всегда локальный вызов ...

Однако, по словам this, аннотация @TransactionAttribute может быть унаследована ... Так,

Для того, чтобы поставить этот вид чтобы работать, вы должны:

1) Объявите метод в вашем бизнес-интерфейсе, который является интерфейсом Importer.

2) Обозначает интерфейс Importer как ваш локальный интерфейс.

3) На вашем FileReader Singleton, получите прокси-сервера вашего Импортера Bean, используя аннотацию @EJB. Если вы используете аннотации CDI (например, @Inject), контейнер будет вводить объекты CDI, а не EJB Proxies! (Будьте осторожны с этим)

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) Измените ваш ExampleImporter так:

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

Если вам действительно нужно использовать CDI Beans вместо прокси-серверов EJB в вашем Singleton Class, вам нужно будет использовать аннотацию CDI @Transactional CDI ... И ваш код также должен быть реорганизован.

+0

Спасибо за ваш ответ. Я попробовал ваше решение, но я всегда получаю WFLYEJB0051: Не удалось найти [...] Импортер EJB [...] ExampleImporter. Я добавил аннотацию «@Local» на интерфейс. –

+0

Мне нужно увидеть ваш код, чтобы помочь вам больше ... можете ли вы обновить свой вопрос с помощью модифицированного кода? –

+0

Я редактировал код. Заранее спасибо –