Hi all,

I played with this simple code in a session EJB and realised that the merge 
operation of EntityManager is very slow (more than one second):


  | public void transfer(Account from, Account to, double value) throws 
AccountOverdrawException, IllegalArgumentException {
  | try
  | {
  |     to.deposit(value);
  |     em.merge(to);
  |     from.withdraw(value);
  |     em.merge(from);
  | 
  | }
  | catch (AccountOverdrawException e)
  | {
  |     context.setRollbackOnly();
  |     throw e;
  | }
  | catch (IllegalArgumentException e)
  | {
  |     context.setRollbackOnly();
  |     throw e;
  | }
  | }
  | 

After that, I tried this version which is much faster (about 10ms):


  | public void transfer(Account from, Account to, double value) throws 
AccountOverdrawException, IllegalArgumentException {
  | try
  | {
  |     Account f = em.find(Account.class, from.getAccountID());
  |     Account t = em.find(Account.class, to.getAccountID());
  |     t.deposit(value);
  |     f.withdraw(value);
  | 
  | }
  | catch (AccountOverdrawException e)
  | {
  |     context.setRollbackOnly();
  |     throw e;
  | }
  | catch (IllegalArgumentException e)
  | {
  |     context.setRollbackOnly();
  |     throw e;
  | }
  | }
  | 

My first guess was that it might be slow because of cascaded merge of 
associated objects inside Account (see code below). But then I read in the EJB 
specification that by default there is no cascading, i.e., it has to be 
explicetly set in the annotations. Is there any other thing I'm currently not 
aware of that causes the difference.

Thanks,
Thorsten






  | @Entity
  | public class Account implements Serializable
  | {
  |     private static final long serialVersionUID = 7443656659402964861L;
  |     
  |     private double balance;
  |     private long accountID;
  |     private Customer customer;
  |     private Bank bank;
  |     
  |     Account()
  |     {
  |             super();
  |     }
  |     
  |     public Account(Customer owner)
  |     {
  |             this.customer = owner;
  |     }
  |     
  |     @Id
  |     @GeneratedValue(strategy = GenerationType.SEQUENCE)
  |     public long getAccountID()
  |     {
  |             return accountID;
  |     }
  |     
  |     void setAccountID(long newID)
  |     {
  |             this.accountID = newID;
  |     }
  | 
  |     @Column
  |     public double getBalance()
  |     {
  |             return balance;
  |     }
  |     
  |     void setBalance(double newBalance)
  |     {
  |             this.balance = newBalance;
  |     }
  | 
  |     @ManyToOne
  |     public Bank getBank()
  |     {
  |             return bank;
  |     }
  | 
  |     public void setBank(Bank bank)
  |     {
  |             this.bank = bank;
  |     }
  | 
  |     @ManyToOne
  |     public Customer getCustomer()
  |     {
  |             return customer;
  |     }
  |     
  |     void setCustomer(Customer newCustomer)
  |     {
  |             this.customer = newCustomer;
  |     }
  | 
  |     /**
  |      * @param amount Deposit the given amount to the account.
  |      * @throws IllegalArgumentException if the given amount is less than 
zero.
  |      */
  |     public void deposit(double amount)
  |     {
  |             if (amount < 0) throw new IllegalArgumentException("Deposit of 
negative amount is not allowed");
  |             setBalance(getBalance() + amount);
  |     }
  |     
  |     /**
  |      * @param amount Withdraw the given amount from the account.
  |      * @throws IllegalArgumentException if the given amount is less than 
zero.
  |      * @throws AccountOverdrawException in case given amout is greather 
than acount balance.
  |      */
  |     public void withdraw(double amount) throws AccountOverdrawException
  |     {
  |             if (amount < 0) throw new IllegalArgumentException("Withdraw of 
negative amount is not allowed");
  |             if (amount > balance) throw new AccountOverdrawException("The 
operation would lead to overdrawing the account and was rejected.");
  |             setBalance(getBalance() - amount);
  |     }
  | }
  | 

Note that Customer in turn has a list of Account(s) and Bank has a list of 
Customer(s) and Account(s), whereby the fetch type of those properties is set 
to lazy.

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

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3990132
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to