On Thu, Apr 08, 2004 at 11:48:47AM +0100, Jeremy Russell wrote:
> First, my apologies if this is the wrong list to be asking this question on,
> but please do point me to the correct list if I'm wrong.

No problem, excuse the delay--we are in heavy EJB 2.1 development at the moment.

> 
> I'm experimenting and trying to learn more about J2EE, specifically for
> access to Oracle databases.
> 
> I've been trying to extend and adapt the CMP Entity bean example from
> http://www.openejb.org/cmp_entity_postgresql.html and make it work with
> Oracle 9i.  My simple client works fine with Oracle but I'm getting issues
> when I try to use transactions as per the source example below.

Exposing comp/UserTransaction to non-ejb clients is a J2EE spec only
type of thing where ther is a "client container" that can manage the
transactional state.  There is a deployment descriptor for these
clients and everything.  The information from the client's deployment
descriptor would be used to setup the client's JNDI namespace,
allowing it to lookup things in the java:comp style.  

The EJB spec itself only supports exposing comp/UserTransaction to
session beans with bean-managed transactions.  Further, non-J2EE app
clients don't get to lookup things using the "java:" prefix and have
to grab an InitialContext using properties that will set it up
specifically to talk to the server.

As OpenEJB isn't an EJB-only container, it isn't possible to get a
java:comp/UserTransaction from outside an EJB.  We do however, stuff the
TransactionManager in JNDI as required for J2EE Connector Architecture
support (crazy all the specs one has to worry about).  You could grab
the TransactionManager and work with it directly.

   ctx.lookup("java:comp/TransactionManager");
   ctx.lookup("java:openejb/TransactionManager"); // also works

Not, this would only work when using OpenEJB embedded, the actual
transaction manager wouldn't be there normally.

I'd recommend, though, it's a far better idea to move the transaction
processing off the client and into a stateful or stateless session.
This get's your transaction processing one tier closer to the database
and will make your app much more portable.

Hope this helps.

-David

> The statement where the issue occurs is:
> 
>       UserTransaction userTransaction =
>         (UserTransaction)ctx.lookup( "java:comp/env/UserTransaction" );
> 
> When I execute the program, I get the following:
> 
> C:\my\app>runEmployeeClient1
> Starting EmployeeClient
> OpenEJB 0.9.2    build: 20030605-0409
> http://openejb.sf.net
> Looking up transaction
> Exception in thread "main" javax.naming.NotContextException: comp is not a
> subcontext
>         at tyrex.naming.EnvContext.internalLookup(EnvContext.java:280)
>         at tyrex.naming.EnvContext.lookup(EnvContext.java:212)
>         at tyrex.naming.java.JavaContext.lookup(JavaContext.java:147)
>         at javax.naming.InitialContext.lookup(InitialContext.java:347)
>         at org.acme.employee.EmployeeClient1.main(EmployeeClient1.java:32)
> 
> C:\my\app>
> 
> I've also tried lookups on the following with the associated results:
> 
>   java:comp/UserTransaction
>   Exception in thread "main" javax.naming.NotContextException: comp is not a
> subcontext
> 
>   UserTransaction
>   Exception in thread "main" javax.naming.NameNotFoundException: Name
> "UserTransaction" not found.
> 
> I'm really tearing my hair out with this - can someone give me even a clue
> as to what I'm doing wrong?
> 
> Thanks in advance
> 
> Jeremy Russell
> 
> Here's my modified source code:
> 
> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
> package org.acme.employee;
> 
> import javax.naming.Context;
> import javax.naming.InitialContext;
> import javax.rmi.PortableRemoteObject;
> import java.util.Properties;
> import javax.transaction.*;
> 
> public class EmployeeClientTx
> {
>    public static void main( String[] args )
>            throws Exception
>    {
>       System.out.println("Starting EmployeeClient");
>       Properties env = new Properties();
>       String jndiProvider = "org.openejb.client.LocalInitialContextFactory";
>       env.put( "java.naming.factory.initial", jndiProvider );
>       env.put( "openejb.home", "c:\\openejb-0.9.2");
>       Context ctx = new InitialContext( env );
>       System.out.println ("Looking up transaction");
> 
>       // Problem statement is next
>       UserTransaction userTransaction =
>         (UserTransaction)ctx.lookup( "java:comp/UserTransaction" );
> 
>       Object obj = ctx.lookup( "EmployeeBean" );
>       obj = PortableRemoteObject.narrow( obj, EmployeeHome.class );
>       EmployeeHome home = ( EmployeeHome ) obj;
> 
>       userTransaction.begin();
>       Employee empl_create = home.create( "Jacek", "Laskowski",
>             "OpenEJB-" + System.currentTimeMillis() + "@SF.net" );
> 
>       Integer primaryKey = ( Integer ) empl_create.getPrimaryKey();
> 
>       Employee empl_find = home.findByPrimaryKey( primaryKey );
> 
>       System.out.println( "Are the \"create\" and \"find\" users identical ?
> "+
>             empl_create.isIdentical( empl_find ) );
>       userTransaction.commit();
> 
>       empl_find.says( "Hello OpenEJB World!" );
>       //empl_find.remove();
>    }
> }
> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> 
> 
> 

Reply via email to