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()); setLockedFl(Boolean.FALSE); setInactiveFl(Boolean.FALSE); return null ; } //end ejbCreate() public void ejbPostCreate( Integer customerNo, Integer typeCd, String unencryptedCardNo, java.util.Date expirationDt, String nameOnCard ) { } //end ejbPostCreate() //CMP FIELDS public abstract Integer getCustomerCCNo() ; public abstract void setCustomerCCNo( Integer customerCCNo ) ; public abstract Integer getCustomerNo() ; public abstract void setCustomerNo( Integer customerNo ) ; public abstract Integer getTypeCd() ; public abstract void setTypeCd( Integer typeCd ) ; public abstract String getCardNo() ; public abstract void setCardNo( String cardNo ) ; public abstract java.util.Date getExpirationDt() ; public abstract void setExpirationDt( java.util.Date expirationDt ) ; public abstract String getNameOnCard() ; public abstract void setNameOnCard( String nameOnCard ) ; public abstract java.util.Date getCreatedDt() ; public abstract void setCreatedDt( java.util.Date createdDt ) ; public abstract Boolean getLockedFl() ; public abstract void setLockedFl( Boolean lockedFl ) ; public abstract Boolean getInactiveFl() ; public abstract void setInactiveFl( Boolean inactiveFl ) ; //CALLBACK METHODS public void setEntityContext( EntityContext entityContext ) {} ; public void unsetEntityContext() {} ; public void ejbLoad() {} ; public void ejbStore() {} ; public void ejbActivate() {} ; public void ejbPassivate() {} ; public void ejbRemove() {} ; public void setUnencryptedCardNo( String unencryptedCardNo ) { setCardNo(getEncryptedCardNo(unencryptedCardNo)); } //end setUnencryptedCardNo() public String getEncryptedCardNo( String unencryptedCardNo ) { if (unencryptedCardNo != null) { try { return new String(Security.encryptRSA(getPublicKey(), unencryptedCardNo.getBytes())); } catch (Exception e) { throw new EJBException(e) ; } //end try } //end if return null ; } //end setUnencryptedCardNo() public Integer ejbFindByCustomerCC( Integer customerNo, String cardNo, java.util.Date expirationDt ) { Integer customerCCNo = null ; if (customerNo != null && cardNo != null && expirationDt != null) { String encryptedCardNo = getEncryptedCardNo(cardNo) ; String sqlText = "SELECT customer_cc_no " + " FROM customer_cc " + " WHERE customer_no = ? " + " AND card_no = ? " + " AND expiration_dt = ? " + " AND NOT inactive_fl " ; Connection connection = null ; PreparedStatement s = null ; ResultSet rs = null ; try { DataSource dataSource = (DataSource)(new InitialContext()).lookup(Global.DATA_SOURCE_NAME) ; connection = dataSource.getConnection() ; s = connection.prepareStatement(sqlText); s.setInt(1,customerNo.intValue()); s.setString(2,encryptedCardNo); s.setDate(3,new java.sql.Date(expirationDt.getTime())); rs = s.executeQuery() ; if (rs.next()) { customerCCNo = new Integer(rs.getInt(1)) ; } //end while rs.close(); s.close(); connection.close(); } catch (Exception e) { System.out.println(sqlText); DBUtil.close(rs); DBUtil.close(s); DBUtil.close(connection); throw new EJBException(e); } //end try } //end if return customerCCNo ; } //end ejbFindByCustomerCC() private static synchronized Key getPublicKey() { if (publicKey == null) { try { publicKey = Security.loadKey(Global.CREDIT_CARD_PUBLIC_KEY_FILE) ; } catch (IOException ioe) { throw new EJBException(ioe); } //end try } //end if return publicKey ; } //end getPublicKey() } //end CustomerCreditCardBean Any hints on what I should try next are welcome. _______________________________________________________________ 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