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