geronimo-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Phani Madgula" <phanibalaji.madg...@gmail.com>
Subject Re: JPA transactions
Date Tue, 17 Jun 2008 04:21:12 GMT
Thanks..I was trying different combinations and finally got confused. Well,
as suggested (also David Blevins said earlier), I would always try to use
JTA transactions incase I am using EM in an EJB.

Thanks
Phani

On Mon, Jun 16, 2008 at 11:09 PM, David Jencks <david_jencks@yahoo.com>
wrote:

>
> On Jun 16, 2008, at 5:21 AM, Phani Madgula wrote:
>
> Hi,
>
> I tried to create a application managed entity manager as follows.
>
> persistence.xml
> -----------------------
> <?xml version="1.0" encoding="UTF-8"?>
> <persistence    xmlns="http://java.sun.com/xml/ns/persistence"
>                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> version="1.0"
>                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
> http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
>
>     <persistence-unit name="AccountUnit" transaction-type="RESOURCE_LOCAL">
>
>         <description>BeanManagedJPA</description>
>
>
> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
>
>         <jta-data-source>AccountDS</jta-data-source>
>
>         <class>sample.jpa.Account</class>
>         <class>sample.jpa.Person</class>
>
>     </persistence-unit>
> </persistence>
>
> Here the 'AccountDS' is the datasource deployed over 'AccountDB' in
> embedded derby database.
> ---------------
>
> I have the stateful 'AccountBean' that has the following code
> ---------------
> @Stateful
> @Local(AccountInterface.class)
> @TransactionManagement(TransactionManagementType.BEAN)
> public class AccountBean implements AccountInterface{
>
>     @PersistenceUnit(unitName="AccountUnit")
>      private EntityManagerFactory emf;
>
>     private EntityManager em;
>
>     Account account;
>     Person person;
>
>     @PostConstruct
>     public void init(){
>         em = emf.createEntityManager();
>     }
>
>     public void initialize(int accountNumber){
>
>         account = em.find(Account.class, accountNumber);
>
>         if(account == null)throw
>            new IllegalStateException("Account number ("+accountNumber+")
> not found");
>
>         person = em.find(Person.class, account.getPersonId());
>
>         if(person == null)throw new IllegalStateException
>          ("Person Id("+account.getPersonId()+
>            ") not found. There is a descripancy in the database for account
> number
>           ("+accountNumber+")");
>     }
>
>     [...]
>
>         public void updateAllValues(String address, String personName,
> double balance){
>             em.getTransaction().begin();
>             System.out.println("Local Transaction Begin-->");
>             setAddress(address);
>             setPersonName(personName);
>             setBalance(balance);
>             em.getTransaction().commit();
>             System.out.println("Local Transaction Commit-->");
>     }
>
>     [...]
>         public void withdraw(double amount){
>
>             if(amount > getBalance())
>
>              throw new IllegalStateException("The amount("+amount+
>               ") to be withdrawn is more than the
>               available balance("+getBalance()+")");
>
>             try{
>                 System.out.println("Method withdraw : message ---> 1");
>                 em.joinTransaction();
>                 System.out.println("Method withdraw : message ---> 2");
>                 setBalance(getBalance() - amount);
>                 System.out.println("Method withdraw : message ---> 3");
>         }catch(Exception e){
>             throw new IllegalStateException(e);
>         }
>
>     }
>
>     public void deposit(double amount){
>         try{
>             em.joinTransaction();
>             setBalance(getBalance() + amount);
>         }catch(Exception e){
>             throw new IllegalStateException(e);
>         }
>
>     }
>
> The setAddress(address), setPersonName(personName), setBalance(balance)
> methods simply set the values to 'Account' and 'Person' entities declared at
> the class level. I also call 'initialize()' method to initialize 'person'
> and 'account' fields in the stateful session bean. Please also note that
> @TransactionManagement(TransactionManagementType.BEAN) is declared.
> ---------------
>
> The 'updateAllValues()' method uses local transaction to update name,
> address, balance fields in 'account' and 'person' entities. It is expected
> that the method is called with no active transaction.
>
> However, 'withdraw(amount)' and 'deposit(amount)' methods are called in a
> transaction. Hence, the entity managers are joined to the active
> transaction.
>
>
> I think this is your mistake.  Since you declared the ejb to have
> bean-managed tx, when you call any method on the ejb, any existing jta
> transaction (such as the one you just started in the servlet using
> UserTransaction) is suspended so that your ejb can do its own transaction
> control.  I don't think you can mix the styles of tx control as you appear
> to be trying to do.
>
> Also I don't think that a resource-local em is enrolled in any jta
> transactions under any circumstances, although I'm not too sure about this.
>  I'm pretty sure it doesn't happen without a method call.
>
>
> thanks
> david jencks
>
>
>
> The typical web client for the bean is as follows.
> ---------------
>
>     [...]
>
>     int debitAccount =
> Integer.parseInt(request.getParameter("accountNumber1"));
>     int creditAccount =
> Integer.parseInt(request.getParameter("accountNumber2"));
>
>     double amount = Double.parseDouble(request.getParameter("amount"));
>
>     Context ctx = new InitialContext();
>
>     AccountInterface debitAccountBean =
> (AccountInterface)ctx.lookup("java:comp/env/ejb/AccountInterface");
>     debitAccountBean.initialize(debitAccount);
>
>     AccountInterface creditAccountBean =
> (AccountInterface)ctx.lookup("java:comp/env/ejb/AccountInterface");
>     creditAccountBean.initialize(creditAccount);
>
>     UserTransaction ut =
> (UserTransaction)ctx.lookup("java:comp/UserTransaction");
>
>     ut.begin();
>
>     debitAccountBean.withdraw(amount);
>     creditAccountBean.deposit(amount);
>
>     ut.commit();
>
>     [...]
> ---------------
>
> When I exceute this part of code, I am getting the following exception at
> the point where 'em.joinTransaction()' is performed in the
> 'withdraw(amount)' method above.
>
> *********************
> Method withdraw : message ---> 1
> 14:47:38,828 ERROR [[jsp]] Servlet.service() for servlet jsp threw
> exception
> java.rmi.NoSuchObjectException: Not Found
>         at
> org.apache.openejb.core.stateful.StatefulInstanceManager.activateInst
> ance(StatefulInstanceManager.java:317)
>         at
> org.apache.openejb.core.stateful.StatefulInstanceManager.obtainInstan
> ce(StatefulInstanceManager.java:282)
>         at
> org.apache.openejb.core.stateful.StatefulInstanceManager.getBeanEntry
> (StatefulInstanceManager.java:560)
>         at
> org.apache.openejb.core.stateful.StatefulInstanceManager.setBeanTrans
> action(StatefulInstanceManager.java:126)
>         at
> org.apache.openejb.core.stateful.StatefulBeanManagedTxPolicy.afterInv
> oke(StatefulBeanManagedTxPolicy.java:77)
>         at
> org.apache.openejb.core.stateful.StatefulContainer._invoke(StatefulCo
> ntainer.java:467)
>         at
> org.apache.openejb.core.stateful.StatefulContainer.businessMethod(Sta
> tefulContainer.java:413)
>         at
> org.apache.openejb.core.stateful.StatefulContainer.invoke(StatefulCon
> tainer.java:271)
>         at
> org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbO
> bjectProxyHandler.java:217)
>         at
> org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectPr
> oxyHandler.java:77)
>         at
> org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHa
> ndler.java:321)
>         at
> org.apache.openejb.util.proxy.Jdk13InvocationHandler.invoke(Jdk13Invo
> cationHandler.java:49)
>         at $Proxy152.withdraw(Unknown Source)
>         at
> org.apache.jsp.TransferAmount_jsp._jspService(TransferAmount_jsp.java
> :85)
>         at
> org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
>         at
> org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper
> .java:388)
>         at
> org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:3
> 20)
>         at
> org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
>         at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
> icationFilterChain.java:290)
>         at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
> ilterChain.java:206)
>         at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV
> alve.java:233)
>         at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextV
> alve.java:175)
>         at
> org.apache.geronimo.tomcat.valve.DefaultSubjectValve.invoke(DefaultSu
> bjectValve.java:56)
>         at
> org.apache.geronimo.tomcat.GeronimoStandardContext$SystemMethodValve.
> invoke(GeronimoStandardContext.java:406)
>         at
> org.apache.geronimo.tomcat.valve.GeronimoBeforeAfterValve.invoke(Gero
> nimoBeforeAfterValve.java:47)
>         at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j
> ava:128)
>         at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j
> ava:102)
>         at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal
> ve.java:109)
>         at
> org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:
> 563)
>         at
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.jav
> a:263)
>         at
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java
> :844)
>         at
> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce
> ss(Http11Protocol.java:584)
>         at
> org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:44
> 7)
>         at java.lang.Thread.run(Thread.java:803)
> ******************
>
> I verified with both AG2.1 and AG2.1.1. Can somebody throw some light on
> this issue??
>
> Thanks
> Phani
>
>
>
>
>
>
>
>

Mime
View raw message