[jboss-user] [JBossWS] - Re: Writing a client - no examples for BindingProvider based

mjhammel do-not-reply at jboss.com
Fri Jan 4 19:53:21 EST 2008


I got a little further now.  First, http://weblogs.java.net/blog/ss141213/archive/2005/12/dont_use_persis_1.html explains the problem a bit - you can't use injection in Web apps, which I assume translates to Web Services.  So I used the technique listed in the blog.  

This worked, eventually, after I added a couple of lines to my persistence.xml, as suggested by the JBOSS App Server entity config documentation (http://docs.jboss.org/ejb3/app-server/reference/build/reference/en/html/entityconfig.html#d0e193).

updated persistence.xml
<persistence>
  | 
  |     <persistence-unit name="Crunch">
  |         <jta-data-source>java:/CrunchDS</jta-data-source>
  |         <properties>
  |             <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
  |             <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
  |             <property name="hibernate.connection.url" value="jdbc:mysql://localhost/crunch"/>
  |             <property name="hibernate.connection.username" value="root"/>
  |             <property name="jboss.entity.manager.jndi.name" value="java:/CrunchPersistence"/>
  |             <property name="jboss.entity.manager.factory.jndi.name" value="java:/CrunchFactory"/>
  |         </properties>
  |     </persistence-unit>
  | </persistence>

The two jndi related properties bound the names specified in the property to the application so that they could be referenced an InitialContext.lookup() (see code below).

Now I can see the Session Bean retrieving the data from the database, but then it immediately complains about some "lazy" thing:

17:11:24,689 INFO  [STDOUT] Subscriber.find(): em is not null; returning subscriber for guid = CRUNCH-DEFAULT-SUPERUSER
  | 17:11:25,015 INFO  [STDOUT] Subscriber name : SuperUser
  | 17:11:25,015 INFO  [STDOUT] Subscriber email: admin at localhost
  | 17:11:25,176 ERROR [LazyInitializationException] failed to lazily initialize a collection of role: com.cei.crunch.ejb.Subscriber.crunchroleses, no session or session was closed

It should be noted that "crunchroleses" is a field in a generated class.  The class, com.cei.crunch.ejb.Subscriber, is generated by the reverse engineering process provided through Hibernate in order to generate EJB code for an existing database.  So maybe there is some (yet more) additional configuration of Hibernate that needs to be done.

My Web Services code now looks like this:

package com.cei.crunch.server.ws.SubscriberServices;
  | 
  | import javax.ejb.*;
  | import javax.jws.WebService;
  | import javax.jws.WebMethod; 
  | import javax.jws.soap.SOAPBinding;
  | import javax.persistence.*;
  | import javax.naming.InitialContext;
  |         
  | import com.cei.crunch.server.util.SubscriberUtil;
  | import com.cei.crunch.ejb.Subscriber;
  |  
  | /* Make this an EJB3 service endpoint. */
  | @Stateless
  | @Remote(SubscriberServices.class)
  |    
  | /* Make this an Web Services endpoint. */
  | @WebService(endpointInterface = "com.cei.crunch.server.ws.SubscriberServices.SubscriberServicesEndpoint")
  | @SOAPBinding(style = SOAPBinding.Style.RPC)
  |  
  | /**
  |  * The .Crunch interface to Subscriber Services
  |  */
  | public class SubscriberServices implements SubscriberServicesEndpoint {
  |  
  |     @WebMethod
  |     public Subscriber findSubscriber(String guid)
  |     {
  |         Subscriber s;
  |         SubscriberUtil su = new SubscriberUtil();
  |  
  |         s = su.find(guid);
  |         if ( s == null )
  |             System.out.println("su.find() returned null.");
  |         return s; 
  |     }
  |    
  | }  

My Session Bean code, which is called by the Web Services code above, looks like this:

package com.cei.crunch.server.util;
  | 
  | import javax.ejb.*;
  | import javax.jws.soap.SOAPBinding;
  | import javax.persistence.*;
  | import javax.naming.InitialContext;
  | import javax.transaction.UserTransaction;
  | import javax.annotation.Resource;
  | 
  | import com.cei.crunch.ejb.Subscriber;
  | 
  | /* Make this an EJB3 service endpoint. */
  | @Stateless
  | 
  | /**
  |  * The .Crunch interface to Subscriber Services
  |  */
  | public class SubscriberUtil implements SubscriberUtilInterface {
  | 
  |     @Resource
  |     private UserTransaction utx;
  | 
  |     public Subscriber find(String guid)
  |     {
  |         InitialContext ctx = null;
  |         EntityManager em = null;
  |         try {
  |             ctx = new InitialContext();
  |             em =  (EntityManager) ctx.lookup("java:/CrunchPersistence");
  |         }
  |         catch (Exception e)
  |         {
  |             // throw new WebServiceException(ex);
  |             System.out.println("Subscriber.find(): context lookup failure.");
  |             e.printStackTrace();
  |             return null;
  |         }
  | 
  |         if ( em == null )
  |         {
  |             System.out.println("Subscriber.find(): em is null; can't find subscriber");
  |             return null; 
  |         }
  |         else 
  |         {
  |             Subscriber s = null;
  |             System.out.println("Subscriber.find(): em is not null; returning subscriber for guid = " + guid);
  |             try {
  |                 utx = (UserTransaction) ctx.lookup("java:/comp/UserTransaction");
  |                 utx.begin();
  |                 s = em.find(Subscriber.class, guid);
  |                 utx.commit();
  |             }
  |             catch (Exception e)
  |             {
  |                 System.out.println("Subscriber.find(): find problem.");
  |                 e.printStackTrace();
  |             }
  |             if ( s != null )
  |             {
  |                 System.out.println("Subscriber name : " + s.getFirstname());
  |                 System.out.println("Subscriber email: " + s.getEmailAddress());
  |             }
  |             return s;
  |         }
  |     }
  | 
  | }

You'll note that I manually create a UserTransaction here.  This is because if I don't do this, no transaction is injected into the Session Bean by the @Resource (I don't know why).  And if I don't create the UserTransaction before referencing the EntityManager (em), I get a null pointer exception when I do reference it.

My best guess at this is that the UserTransaction is in the wrong place - it may need to go in the Web Services class before it calls the Session Bean.  However, that's pretty much a WAG at this point.

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4117235#4117235

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4117235



More information about the jboss-user mailing list