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