2013-04-25 55 views
1

我試圖獲得@Singleton SessionBean中的TransactionManager - EJB 3.1 - 來控制我的事務範圍,因爲我必須訪問@PostConstruct方法上的數據庫。如果發生異常,我不能讓Container RollBack,因爲它會引發TransactionRolledbackException:setRollbackOnly在一個單獨的後期構造方法中調用。我如何獲得WebSphere 8.0上的TransactionManager?

我正在使用JTA數據源並定義了@TransactionManagement(TransactionManagementType.BEAN)來覆蓋事務的控制。

@Resource private TransactionManager transactionManager;

返回給我一個NullPointerException當我嘗試做一個「transactionManager.begin();」。有誰知道如何解決這個問題?

UPDATE:

我使用的代碼是這樣的:

@Startup 
    @Singleton 
    @TransactionManagement(TransactionManagementType.BEAN) 
    public class RuntimeContextEJB 

{ 

    @EJB 
    private RepositoryRecursosExternosFactoryEJB repositoryRecursosExternosFactoryEJB; 

    @EJB 
    private MetodologiaIndiceLiquidezFactoryEJB  metodologiaIndiceLiquidezFactoryEJB; 

    @EJB 
    private FuncaoMatematicaFactoryEJB    funcaoMatematicaFactoryEJB; 

    private boolean         bootstrapRunning = false; 

    private List<String>       dadosMercadoMonitorados; 

    @PersistenceContext(unitName = "crv-persistence-unit") 
    private EntityManager       entityManager; 

    @Resource 
    private TransactionManager transactionManager; 


    @PostConstruct 
    public void init() 
    { 
     // comentário 
     MotorCalculoContext.setupMotorCalculoContext(repositoryRecursosExternosFactoryEJB, metodologiaIndiceLiquidezFactoryEJB, 
       funcaoMatematicaFactoryEJB); 
     carregaDadosMercadoMonitorados(); 

    } 


    public void sinalizarInicioBootstrap() 
    { 
     bootstrapRunning = true; 
    } 


    public void sinalizarTerminoBootstrap() 
    { 
     bootstrapRunning = false; 
    } 


    public boolean isBootstrapRunnnig() 
    { 
     return bootstrapRunning; 
    } 

    public void carregaDadosMercadoMonitorados() 
    { 




     try 
     { 

      transactionManager.begin(); 

      this.dadosMercadoMonitorados = (List<String>) entityManager 
        .createQuery(
          "SELECT DISTINCT(p.parametro.codigoDadoMercado) FROM PlanoExecucaoPasso p WHERE p.parametro.codigoDadoMercado <> '' AND p.parametro.codigoDadoMercado <> '0'") 
        .getResultList(); 
     } 
     catch (Exception e) 
     { 
     } 

    } 

} 

我覺得應該有一個JNDI ADRESS對@Resource註釋,一個是具體針對WebSphere補充,但我真的找不到至極。

更新:

爲什麼在容器託管注入上使用JNDI?由於我從直接注入中獲得了空指針異常,因此試圖像使用前一樣使用。從OReilly Enterprise Java Beans 3.1第6版開始,

@Resource(mappedName = "java:/TransactionManager") 
//mappedName is vendor-specific, and in this case points to an address in JNDI 

試過這個沒有成功。

UPDATE

的WebSphere是沒有得到我們的豆註釋 - 不知道爲什麼 - 這樣的註解:

@TransactionManagement(TransactionManagementType.BEAN) 

不能正常工作。因此,編輯了de ejb-jar.xml並添加了以下代碼:

<transaction-type>Bean</transaction-type> 

和UserTransaction起作用。感謝您的答案。

+0

mappedName在websphere中不受支持。 – 2013-04-27 02:18:49

回答

2

當你有豆管理的事務,您不使用javax.transaction.TransactionManager而是你使用javax.transaction.UserTransaction

然後調用開始,提交....等UserTransaction接口。

答更新時間:所有的

1)首先,正如我所說,不使用TransactionManager。使用UserTransaction

2)如你想知道JNDI名稱UserTransaction對象。它是java:comp/UserTransaction。但是隻有當你的組件沒有被管理時你才需要它。 ie: Servlet,EJB。該過程被稱爲進行手動調用JNDI API

3)提供提交()回滾()。他們都不在場。

我在看你的班級,它看起來沒問題。

那麼,問題在哪裏? (可能性)

1)您的類不被視爲EJB(容器管理),這就是爲什麼注入失敗。

2)事務服務未在EJB @Startup之前啓動,或者無法啓動。

3)JTA數據源的persistence.xml配置。在這種情況下,嘗試:

@Resource 
private EJBContext context; 

userTransaction = context.getUserTransaction(); 

注:請同時提供完整的堆棧跟蹤和的persistence.xml以查明確切的問題。

+0

感謝您的回答。做到了,相同的結果。 – 2013-04-26 03:34:54

+1

請發佈您的bean代碼。 – 2013-04-26 04:11:30

+0

@GuilhermeRocha,請檢查更新的答案。 – 2013-04-27 00:38:46

0

下面是一些使用UserTransaction正確運行以控制事務的示例代碼。

@Singleton 
@Startup 
@TransactionManagement(TransactionManagementType.BEAN) 
public class SampleUT { 

Logger logger = Logger.getLogger(SampleUT.class.getName()); 

@Resource 
private UserTransaction ut; 

@PostConstruct 
public void postConstruct() 
{ 
    logger.info("PostConstruct called"); 

    try { 
     ut.begin(); 
... 

你得到的NullPointerException可能與你試圖在你的EJB的Constructor中使用注入的資源有關。你應該知道注入的引用永遠不可用,直到EJB的構造函數完成,所以如果你嘗試在構造函數中使用任何注入的引用,它將拋出一個NullPointerException異常。

+0

感謝您的回答。我知道注入是在bean實例準備好後進行的,這就是爲什麼我在@PostConstruct方法內使用注入引用的原因。一旦我開始工作,明天就會發布bean代碼。 – 2013-04-26 04:52:07

1

除非您想在某些情況下掛起()或繼續()關聯事務,否則不需要在編程(BMT)會話bean中使用事務管理器,而是使用UserTransaction。

但是,您可以使用靜態方法的getTransactionManager()由 com.ibm.ws.Transaction.TransactionManagerFactory類獲得在WebSphere事務管理提供參考。

public TransactionManager getTransactionManager() { 
    return TransactionManagerFactory.getTransactionManager(); 
}