Re: [JBoss-user] Need Hints on Finding Tx Bug
Jon, Thanks for the info. I seemed to have 'fixed' my problem as well, although I'm not sure what I did to fix it. I built a new JBoss from this morning's CVS, using jdk1.4 (due to that horrible protected instance variable not seen by subclasses' inner classes bug in jdk 1.3) and now the exception has gone away. I'm not convinced it won't show up again, but at least for now development may proceed. I'll definitely keep your findings in mind when writing custom finders. Justin Well Justin, I have solved the issue, although I think this may qualify for a bug. Basically, it boils down to returning null in a custom finder. I couldn't find documentation on implementing a custom finder in which a single record was returned instead of a Collection. The method signiture for a custom finder returning a Collection in the JBossCMP book does not include throws FinderException so I wrongly assumed that it couldn't have one. I thought that returning null would do the trick. I was wrong. When JBoss gets a null back from the custom finder, it generates a not null object and returns. Any call on this object results in the tx error. It is conceivable that you are experiencing the same issue if your finder returns a null PK within the collection. The fix for me was to throw a FinderException in the custom finder when the row was not found. Obviously, I am in error in that I did not know the proper way to specify a no result in the customer finder. However, I think JBoss should handle this a little better given that it is not that hard to create. Maybe JBoss should throw a FinderException if the custom finder returns null or a non-valid PK (i.e. not in DB). I guess it is concievable to have a null as a valid PK value (although I would shot any developer of mine who did that). Even if you do not want to take the hit and check the DB for a valid value right away, when a method call is made, a Tx error complicates things. Even returning a NULL object would have been better I think. ___ Don't miss the 2002 Sprint PCS Application Developer's Conference August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm ___ JBoss-user mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/jboss-user
Re: [JBoss-user] Need Hints on Finding Tx Bug
I am getting the very same error message in a very similar use case. The only difference I can see is that all the methods of the offending bean are set to 'Required' rather than 'RequiresNew'. The error occurs when I try to call the get methods of the bean through a local interface in a session bean. I lookup the bean with the findByPrimaryKey method like you do, but in my case, the record already exists in the DB. Perhaps this problem is not related to the tx setting, since yours did not fail with RequiresNew in a simple case, and mine fails with Required in my case? I am in the process of creating a simple test for this problem. I'll post the results here if/when I find out anything of potential use. I am using JBoss3.0.0RC2 and have a complex process that creates new orders as they are submitted from the web. On order submission, a credit card is authorized via SSL. If the credit card is declined then the order is rolled back, however the credit card information must stay because we must have a log of all calls to the credit card interface. To accomplish this, I have two methods set to RequiresNew. One is the method that creates the credit card bean and the other is the one that creates the credit card interface log entry bean. All other methods have transactioning set to Required. I have had success in various tests done with simple Entity beans and a Session bean with the RequiresNew method(s). I get an odd error when I use the more complex credit card bean: java.rmi.ServerException: removing bean lock and it has tx set! I have narrowed the issue to a very specific call to the following method: public CustomerCreditCardLocal getCustomerCreditCard( Integer customerNo, Integer ccTypeCd, String ccNum, java.util.Date ccExpDate, String nameOnCard ) { try { CustomerCreditCardLocalHome creditCardHome = (CustomerCreditCardLocalHome)getInitialContext().lookup(local/+CustomerCr editCard.BEAN_NAME) ; CustomerCreditCardLocal creditCard = null ; try { creditCard = creditCardHome.findByCustomerCC(customerNo, ccNum, ccExpDate) ; } catch (FinderException fe) { } //end try if (creditCard == null) { Integer customerCCNo = ((MoneyHandlerLocal)sessionContext.getEJBLocalObject()).createCustomerCredi tCard(customerNo, ccTypeCd, ccNum, ccExpDate, nameOnCard) ; try { creditCardHome = (CustomerCreditCardLocalHome)getInitialContext().lookup(local/+CustomerCr editCard.BEAN_NAME) ; creditCard = creditCardHome.findByPrimaryKey(customerCCNo) ; } catch (FinderException fe) { } //end try } //end if System.out.println(customerCCNo: +creditCard.getCustomerCCNo().toString()); return creditCard ; } catch (NamingException ne) { throw new EJBException(ne) ; } catch (CreateException ce) { throw new EJBException(ce) ; } //end try } //end getCustomerCreditCard() The createCustomerCreditCard() method is set to RequiresNew and simply calls create on CustomerCreditCardLocalHome and returns the PK. The error occurs on the System.out.println when I try to call getCustomerCCNo() on the newly created bean. What is interesting is that there is no record created in the database. It is also odd that if the credit card entry already exists in the DB then everything works. Even the credit card log creation that uses the same approach to make sure it is in it's own transaction happens without a hitch. The only thing that is different between the credit card bean and all the other beans that have been successful using RequiresNew is that the passed credit card number is being encrypted. I can't understand how that would make a difference. Calling the bean create method from a remote client works fine (thats how I tested the code for when the record already exists). Here is most of the bean definition (package identification removed for client privacy reasons): import java.io.*; import java.sql.*; import java.util.*; import java.security.Key; import javax.ejb.*; import javax.naming.*; import javax.sql.*; import com.atomicpc.db.*; import com.atomicpc.util.*; public abstract class CustomerCreditCardBean implements EntityBean { public static final String SEQUENCE_NAME = customer_cc_no_seq ; private static Key publicKey = null ; //CREATE METHODS public Integer ejbCreate( Integer customerNo, Integer typeCd,
Re: [JBoss-user] Need Hints on Finding Tx Bug
Thanks Justin for sharing the pain. I thought I was alone. I am very interested to see the source where you have duplicated this issue. I would like you to also include your ejb-jar.xml sections. If I can find the exact situation, I may be able to come up with a test case, a work around, or even delve into the JBoss code (the horror). This is a dead stop issue for my project at the moment so I am eager to see what you have. I am getting the very same error message in a very similar use case. The only difference I can see is that all the methods of the offending bean are set to 'Required' rather than 'RequiresNew'. The error occurs when I try to call the get methods of the bean through a local interface in a session bean. I lookup the bean with the findByPrimaryKey method like you do, but in my case, the record already exists in the DB. Perhaps this problem is not related to the tx setting, since yours did not fail with RequiresNew in a simple case, and mine fails with Required in my case? I am in the process of creating a simple test for this problem. I'll post the results here if/when I find out anything of potential use. ___ Don't miss the 2002 Sprint PCS Application Developer's Conference August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm ___ JBoss-user mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/jboss-user
Re: [JBoss-user] Need Hints on Finding Tx Bug
Jon, Here is the original forum post that I found that talks about the same error in a similar case: http://main.jboss.org/forums/thread.jsp?forum=47thread=11678 they talked about messing with the AutoCommit property of the oracle driver. I'm not sure if our problems are related to this or not, as I don't know the scope of this particular error message (although it seems sort of generic). the bean that is having the problems has the following attributes in the enterprise-beans section of its dd: entity ejb-nameCSRequestBean/ejb-name ... persistence-typeContainer/persistence-type prim-key-classjava.lang.String/prim-key-class reentrantFalse/reentrant cmp-version2.x/cmp-version abstract-schema-nameCSRequest/abstract-schema-name ... /entity and the following container-transaction section of its dd: container-transaction method ejb-nameCSRequestBean/ejb-name method-name*/method-name /method trans-attributeRequired/trans-attribute /container-transaction the session bean that calls this entity bean does so in the following manner: (paraphrased for clarity, there is actually a subroutine that assigns all the properties of the bean to the view object inside the for loop) Collection c = csrHome.findAll(); Collection result = new Vector(); System.out.println(result size: + c.size()); for(Iterator i = c.iterator(); i.hasNext();) { LocalCSRequest csr = (LocalCSRequest)i.next(); CSRViewObject vo = new CSRViewObject(); vo.csRequestID = csr.getCSRequestID(); /* This line fails, see stack trace below ( $Proxy38.getCSRequestID ) */ ... result.add(vo); } return result; so basically once i get a reference to the bean and use the local interface to call one of the bean's get() methods, the transaction exception is thrown. this entity bean is actually very simple, nothing more than a few abstract accessors and the required ejb methods. I'm not doing anything fancy here. the stack trace is: 2002-05-17 14:29:34,491 INFO [STDOUT] result size: 1 2002-05-17 14:29:34,736 ERROR [STDERR] java.lang.reflect.UndeclaredThrowableException: 2002-05-17 14:29:34,743 ERROR [STDERR] java.rmi.ServerException: removing bean lock and it has tx set!; nested exception is: java.lang.IllegalStateException: removing bean lock and it has tx set! 2002-05-17 14:29:34,749 ERROR [STDERR] java.lang.IllegalStateException: removing bean lock and it has tx set! 2002-05-17 14:29:34,755 ERROR [STDERR] at org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock.removeRef(QueuedPessimisticEJBLock.java:469) 2002-05-17 14:29:34,761 ERROR [STDERR] at org.jboss.ejb.BeanLockManager.removeLockRef(BeanLockManager.java:78) 2002-05-17 14:29:34,767 ERROR [STDERR] at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:124) 2002-05-17 14:29:34,772 ERROR [STDERR] at org.jboss.ejb.plugins.EntityCreationInterceptor.invoke(EntityCreationInterceptor.java:69) 2002-05-17 14:29:34,778 ERROR [STDERR] at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:96) 2002-05-17 14:29:34,783 ERROR [STDERR] at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:167) 2002-05-17 14:29:34,789 ERROR [STDERR] at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:61) 2002-05-17 14:29:34,795 ERROR [STDERR] at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:129) 2002-05-17 14:29:34,800 ERROR [STDERR] at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:166) 2002-05-17 14:29:34,806 ERROR [STDERR] at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:145) 2002-05-17 14:29:34,811 ERROR [STDERR] at org.jboss.ejb.EntityContainer.invoke(EntityContainer.java:482) 2002-05-17 14:29:34,863 ERROR [STDERR] at org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invoke(BaseLocalProxyFactory.java:304) 2002-05-17 14:29:34,868 ERROR [STDERR] at org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:38) 2002-05-17 14:29:34,873 ERROR [STDERR] at $Proxy38.getCSRequestID(Unknown Source) 2002-05-17 14:29:34,879 ERROR [STDERR] at com.wavespring.cs.ejb.session.CSRequestManagerBean.createCSRViewFromEntity(CSRequestManagerBean.java:257) 2002-05-17 14:29:34,885 ERROR [STDERR] at com.wavespring.cs.ejb.session.CSRequestManagerBean.getAllCSRs(CSRequestManagerBean.java:25) 2002-05-17 14:29:34,890 ERROR [STDERR] at java.lang.reflect.Method.invoke(Native Method) 2002-05-17 14:29:34,895 ERROR [STDERR] at
Re: [JBoss-user] Need Hints on Finding Tx Bug
Thanks, Justin, for the quick response. I had hoped that there would be simularities between the two issues, but I don't see any other than the error message. I am using PostGre on the same machine as JBoss. I have other code that does something very simular to yours without issue. I guess you have also had better luck on PostGre. I wish I could figure out how to generate the error in a test bean. All my tests are successful. Are you doing any operations on the bean or directly to the records prior to accessing them with the finder method? For me, it only happens when I have just created the bean. It is as if the findByPrimaryKey method is being handed a reference to the bean before it has completed the previous transaction. That would explain why I get the Tx error and why the record never makes it into the DB even though the RequiresNew method successfully completed. I even tried using the Remote interface instead of the local with the same results. On Tuesday 21 May 2002 11:42 am, Justin Casp wrote: Jon, Here is the original forum post that I found that talks about the same error in a similar case: http://main.jboss.org/forums/thread.jsp?forum=47thread=11678 they talked about messing with the AutoCommit property of the oracle driver. I'm not sure if our problems are related to this or not, as I don't know the scope of this particular error message (although it seems sort of generic). the bean that is having the problems has the following attributes in the enterprise-beans section of its dd: entity ejb-nameCSRequestBean/ejb-name ... persistence-typeContainer/persistence-type prim-key-classjava.lang.String/prim-key-class reentrantFalse/reentrant cmp-version2.x/cmp-version abstract-schema-nameCSRequest/abstract-schema-name ... /entity and the following container-transaction section of its dd: container-transaction method ejb-nameCSRequestBean/ejb-name method-name*/method-name /method trans-attributeRequired/trans-attribute /container-transaction the session bean that calls this entity bean does so in the following manner: (paraphrased for clarity, there is actually a subroutine that assigns all the properties of the bean to the view object inside the for loop) Collection c = csrHome.findAll(); Collection result = new Vector(); System.out.println(result size: + c.size()); for(Iterator i = c.iterator(); i.hasNext();) { LocalCSRequest csr = (LocalCSRequest)i.next(); CSRViewObject vo = new CSRViewObject(); vo.csRequestID = csr.getCSRequestID(); /* This line fails, see stack trace below ( $Proxy38.getCSRequestID ) */ ... result.add(vo); } return result; so basically once i get a reference to the bean and use the local interface to call one of the bean's get() methods, the transaction exception is thrown. this entity bean is actually very simple, nothing more than a few abstract accessors and the required ejb methods. I'm not doing anything fancy here. ___ Don't miss the 2002 Sprint PCS Application Developer's Conference August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm ___ JBoss-user mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/jboss-user
Re: [JBoss-user] Need Hints on Finding Tx Bug
Well Justin, I have solved the issue, although I think this may qualify for a bug. Basically, it boils down to returning null in a custom finder. I couldn't find documentation on implementing a custom finder in which a single record was returned instead of a Collection. The method signiture for a custom finder returning a Collection in the JBossCMP book does not include throws FinderException so I wrongly assumed that it couldn't have one. I thought that returning null would do the trick. I was wrong. When JBoss gets a null back from the custom finder, it generates a not null object and returns. Any call on this object results in the tx error. It is conceivable that you are experiencing the same issue if your finder returns a null PK within the collection. The fix for me was to throw a FinderException in the custom finder when the row was not found. Obviously, I am in error in that I did not know the proper way to specify a no result in the customer finder. However, I think JBoss should handle this a little better given that it is not that hard to create. Maybe JBoss should throw a FinderException if the custom finder returns null or a non-valid PK (i.e. not in DB). I guess it is concievable to have a null as a valid PK value (although I would shot any developer of mine who did that). Even if you do not want to take the hit and check the DB for a valid value right away, when a method call is made, a Tx error complicates things. Even returning a NULL object would have been better I think. ___ Don't miss the 2002 Sprint PCS Application Developer's Conference August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm ___ JBoss-user mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/jboss-user
[JBoss-user] Need Hints on Finding Tx Bug
I am using JBoss3.0.0RC2 and have a complex process that creates new orders as they are submitted from the web. On order submission, a credit card is authorized via SSL. If the credit card is declined then the order is rolled back, however the credit card information must stay because we must have a log of all calls to the credit card interface. To accomplish this, I have two methods set to RequiresNew. One is the method that creates the credit card bean and the other is the one that creates the credit card interface log entry bean. All other methods have transactioning set to Required. I have had success in various tests done with simple Entity beans and a Session bean with the RequiresNew method(s). I get an odd error when I use the more complex credit card bean: java.rmi.ServerException: removing bean lock and it has tx set! I have narrowed the issue to a very specific call to the following method: public CustomerCreditCardLocal getCustomerCreditCard( Integer customerNo, Integer ccTypeCd, String ccNum, java.util.Date ccExpDate, String nameOnCard ) { try { CustomerCreditCardLocalHome creditCardHome = (CustomerCreditCardLocalHome)getInitialContext().lookup(local/+CustomerCreditCard.BEAN_NAME) ; CustomerCreditCardLocal creditCard = null ; try { creditCard = creditCardHome.findByCustomerCC(customerNo, ccNum, ccExpDate) ; } catch (FinderException fe) { } //end try if (creditCard == null) { Integer customerCCNo = ((MoneyHandlerLocal)sessionContext.getEJBLocalObject()).createCustomerCreditCard(customerNo, ccTypeCd, ccNum, ccExpDate, nameOnCard) ; try { creditCardHome = (CustomerCreditCardLocalHome)getInitialContext().lookup(local/+CustomerCreditCard.BEAN_NAME) ; creditCard = creditCardHome.findByPrimaryKey(customerCCNo) ; } catch (FinderException fe) { } //end try } //end if System.out.println(customerCCNo: +creditCard.getCustomerCCNo().toString()); return creditCard ; } catch (NamingException ne) { throw new EJBException(ne) ; } catch (CreateException ce) { throw new EJBException(ce) ; } //end try } //end getCustomerCreditCard() The createCustomerCreditCard() method is set to RequiresNew and simply calls create on CustomerCreditCardLocalHome and returns the PK. The error occurs on the System.out.println when I try to call getCustomerCCNo() on the newly created bean. What is interesting is that there is no record created in the database. It is also odd that if the credit card entry already exists in the DB then everything works. Even the credit card log creation that uses the same approach to make sure it is in it's own transaction happens without a hitch. The only thing that is different between the credit card bean and all the other beans that have been successful using RequiresNew is that the passed credit card number is being encrypted. I can't understand how that would make a difference. Calling the bean create method from a remote client works fine (thats how I tested the code for when the record already exists). Here is most of the bean definition (package identification removed for client privacy reasons): import java.io.*; import java.sql.*; import java.util.*; import java.security.Key; import javax.ejb.*; import javax.naming.*; import javax.sql.*; import com.atomicpc.db.*; import com.atomicpc.util.*; public abstract class CustomerCreditCardBean implements EntityBean { public static final String SEQUENCE_NAME = customer_cc_no_seq ; private static Key publicKey = null ; //CREATE METHODS public Integer ejbCreate( Integer customerNo, Integer typeCd, String unencryptedCardNo, java.util.Date expirationDt, String nameOnCard ) throws CreateException { setCustomerCCNo(Global.getNextKey(SEQUENCE_NAME)); setCustomerNo(customerNo); setTypeCd(typeCd); setUnencryptedCardNo(unencryptedCardNo); setExpirationDt(expirationDt); setNameOnCard(nameOnCard); setCreatedDt(new java.util.Date());