Guilherme Rocha
Guilherme Rocha

Reputation: 73

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.

Upvotes: 1

Views: 6900

Answers (3)

Mu&#39;ath Baioud
Mu&#39;ath Baioud

Reputation: 41

You don't need to use the Transaction Manager in programmatic (BMT) session beans, unless you want to suspend() or resume() the associated transaction in some cases, use the UserTransaction instead .

However, you can get a reference to the Transaction Manager in websphere by com.ibm.ws.Transaction.TransactionManagerFactory class using the static method getTransactionManager() .

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

Upvotes: 1

Ravi Trivedi
Ravi Trivedi

Reputation: 2360

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.

Upvotes: 2

groo
groo

Reputation: 4448

Here's some sample code that runs properly using UserTransaction to have control over transactions.

@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();
...

The NullPointerException you're getting is probably related to you trying to use the injected resource inside the Constructor of your EJB. You should be aware that the injected reference is never available until the constructor of the EJB is finished, so if you try to use any injected reference inside the constructor, it will throw a NullPointerException.

Upvotes: 0

Related Questions