Search code examples
javawebspheretransactionmanager

how can i obtain TransactionManager on WebSphere 8.0?


I tried to obtain the TransactionManager in a @Singleton SessionBean - EJB 3.1 - to control the scope of my transaction, because i have to access a database on a @PostConstruct method. If an exception occurrs, I cannot let the Container RollBack because it throws the TransactionRolledbackException: setRollbackOnly called from within a singleton post construct method.

I am using a JTA DataSource and defined the @TransactionManagement(TransactionManagementType.BEAN) to override control of the transaction.

@Resource private TransactionManager transactionManager;

returns to me a NullPointerException when i try to do a "transactionManager.begin();". Does anyone knows how to solve this ?

UPDATE:

the code i am using is this:

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

    }

}

I think there should be a JNDI adress to add on the @Resource annotation, one that is specific for WebSphere, but i really can't find wich is.

UPDATE:

why use JNDI on a container managed injection ? Since i am getting a nullpointer exception from a direct injection, tried to use like the ex. on page 305 from OReilly Enterprise Java Beans 3.1 6th edition.

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

tried this with no success.

UPDATE

WebSphere is not getting our beans annotations - can't really know why - so the annotation:

@TransactionManagement(TransactionManagementType.BEAN)

was not working. So, edited de ejb-jar.xml and added the following code:

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

and the UserTransaction worked. Thanks for the answers.


Solution

  • When you have bean managed transaction, you don't use javax.transaction.TransactionManager but instead you use javax.transaction.UserTransaction.

    And then you call begin, commit .... etc of UserTransaction interface.

    Answer Updated:

    1) First of all, as I said, don't use TransactionManager. Use UserTransaction

    2) As you wanted to know the JNDI name of the UserTransaction object. It is java:comp/UserTransaction. But you need this only when your component is not managed. ie: Servlet, EJB. That process is called making a manual call to JNDI API

    3) Provide commit() or rollback(). None of them is present.

    I am looking at your class and it seems alright.

    So, where is the problem ? (possibilities)

    1) Your class is not treated as EJB (container managed) and which is why injection fails.

    2) Transaction service is not started before EJB @Startup or it fails to start.

    3) You have JTA Datasource configured in your persistence.xml. In which case, try:

    @Resource
    private EJBContext context;
    
    userTransaction  = context.getUserTransaction(); 
    

    Note: Please also provide full stack trace and persistence.xml in order to pinpoint exact problem.