1 Reply Latest reply on Nov 21, 2011 3:21 PM by Daniel Rowe

    I need help persisting an Object in a Seam Web Service

    Sola Akanmu Newbie
      Hi All,

      Please I am trying to create a Web Service within the Seam Framework. I have been able to consume it using a sample web client. Now I am trying to persist an object within a WebMethod and I keep getting the error : cannot get Transaction for a JTA Transaction and when I try it without using a transaction, It doesn't work or throw any error at all. I have also tried using UserTransaction but then I get:

      08:02:32,339 ERROR [STDERR]     at org.jboss.seam.ScopeType.getContext(ScopeType.java:121)
      08:02:32,340 ERROR [STDERR]     at org.jboss.seam.Component.getInstance(Component.java:1999)
      08:02:32,341 ERROR [STDERR]     at org.jboss.seam.Component.getInstance(Component.java:1994)
      08:02:32,342 ERROR [STDERR]     at org.jboss.seam.Component.getInstance(Component.java:1967)
      08:02:32,344 ERROR [STDERR]     at org.jboss.seam.Component.getInstance(Component.java:1962)
      08:02:32,345 ERROR [STDERR]     at org.jboss.seam.transaction.Transaction.instance(Transaction.java:39)
      08:02:32,346 ERROR [STDERR]     at com.dtec.T2MDashboard.ws.SmsInterface.sendSms(SmsInterface.java:64)
      08:02:32,348 ERROR [STDERR]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) .....


      See my Codes below:



      package com.dtec.T2MDashboard.ws;

      import java.util.Date;

      import javax.jws.WebMethod;
      import javax.jws.WebService;
      import javax.jws.soap.SOAPBinding;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      import javax.persistence.EntityManager;
      import javax.persistence.EntityManagerFactory;
      import javax.persistence.EntityTransaction;
      import javax.persistence.Persistence;
      import javax.persistence.PersistenceContext;
      import javax.transaction.TransactionManager;
      import javax.transaction.UserTransaction;

      import javax.ejb.Stateful;
      import javax.ejb.TransactionManagement;
      import javax.ejb.TransactionManagementType;

      import org.jboss.seam.annotations.Begin;
      import org.jboss.seam.annotations.FlushModeType;
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Scope;
      import org.jboss.seam.annotations.Transactional;
      import org.jboss.seam.ScopeType;
      import org.jboss.seam.transaction.Transaction;

      import com.dtec.T2MDashboard.SmsMessages;

      @WebService
      @SOAPBinding(style = SOAPBinding.Style.RPC)
      public class SmsInterface {

              @WebMethod
              @Begin(flushMode = FlushModeType.MANUAL)
              @Transactional
              public String sendSms(String message, String destination, String sendtime) {
                      String result = "-1";

                      if (message == null || destination == null || message.trim().equals("")
                                      || destination.trim().equals("")) {
                              result = "1";
                              return result;
                      }
                      SmsMessages smsMessage = new SmsMessages();
                      smsMessage.setMessage(message);
                      smsMessage.setDestination(destination);
                      smsMessage.setDate(new Date());
                      if (sendtime.trim().equals("")) {
                              smsMessage.setScheduledDatetime(new Date());
                      }

                      EntityManagerFactory emf = null;
                      try {
                              emf = (EntityManagerFactory) new InitialContext()
                                              .lookup("java:/T2MDashboardEntityManagerFactory");
                              EntityManager em = emf.createEntityManager();
                              // em.getTransaction().begin(); // UserTransaction txn
                              // =Transaction.instance(); //
                              // txn.begin()
                              UserTransaction ut = Transaction.instance();
                              ut.begin();
                              em.persist(smsMessage); // em.flush();
                              // em.getTransaction().commit();
                              // txn.commit();
                              ut.commit();
                              em.flush();

                              result = "0";
                      } catch (Exception e) { // TODO Auto-generated catch block
                              e.printStackTrace();
                              result = "-1";
                      }

                      return result;
              }

              @WebMethod
              public String registerCustomer() {
                      return "register customer";
              }

              @WebMethod
              public String transactionAlert() {
                      return "transaction alert";
              }
      }


      I would really appreciate your help in resolving this issue.

      Thanks
        • 1. Re: I need help persisting an Object in a Seam Web Service
          Daniel Rowe Newbie
          I have used Lifecycle.beginCall() and Lifecycle.endCall() to solve this (at least I'm pretty sure that is what gets things working for me -- it's be a while since I wrote that code...)

          I don't need to call explicit transaction code (except maybe for rollback on error, but maybe someone else can say that is not necessary?), then, so no need for ut.commit, etc...

          It looks like roughly like this:

          @Stateless
          @WebService(name = "RCMDS", targetNamespace = "com.rcmds.webservices.rcmds")
          public class RCMDSAPI {
             @PersistenceContext(unitName = "mdrc") private EntityManager entityManager;
             @Resource SessionContext ctx; // Session-context (used for explicit transaction rollback)

             @WebMethod(operationName = "someMethod")
             public String someMethod() {
                try {
                   Lifecycle.beginCall();
                  
                   // Persist something
                   SomeObject someObject = ...
                   entityManager.persist(someObject);

                   // Return the result
                   return "persisted";
                }
                catch (Exception e) {
                   blah, blah...
                   return null;
                }
                finally {
                   // If we didn't succeed, roll-back the transaction
                   if (!success) {
                      ctx.setRollbackOnly();
                     
                   Lifecycle.endCall();
                }
             }


          Hope this helps!