You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by kuuldor <ku...@gmail.com> on 2008/01/21 15:27:16 UTC

Weird Performance Problem

Hi everybody,
I'm trying to use OpenJPA in my new project, but when I do some
experiments I encounter a very low performance in inserting records
into database.

My situation is like this:
Database is derby 10.2
A very simple table 'account' having a auto-increment ID, and a 'name'
field of varchar(16), and an 'fullname' field of varchar(32) and
'descript' of varchar(255).
Here is the create table SQL:
create table account (id integer not null generated always as
identity, name varchar(16) not null unique, fullname varchar(32),
descript varchar(255), constraint Account_Primary_ID primary key
(id));
My persistence.xml is like this:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
 version="1.0">
 <persistence-unit name="Test" transaction-type="RESOURCE_LOCAL">
  <provider>
   org.apache.openjpa.persistence.PersistenceProviderImpl
  </provider>
  <class>test.Account</class>
  <properties>
    <property name="openjpa.ConnectionDriverName"
    value="org.apache.derby.jdbc.ClientDriver" />
   <property name="openjpa.ConnectionURL"
    value="jdbc:derby://localhost:1527/tsam2" />
   <property name="openjpa.ConnectionUserName" value="app" />
   <property name="openjpa.ConnectionPassword" value="app" />
   <property name="openjpa.Log" value="none" />
   <property name="openjpa.DataCache" value="true" />
   <property name="openjpa.RemoteCommitProvider" value="sjvm" />
  </properties>
 </persistence-unit>
</persistence>

And the Entity Class is:
package test;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

import javax.persistence.*;

@Entity()
@Table(name="ACCOUNT")
public class Account  implements Serializable {
 //default serial version id, required for serializable classes.
 private static final long serialVersionUID = 1L;
 private Integer id;
 private String descript;
 private String fullname;
 private String name;

    public Account() {
    }

 @Id()
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 @Column(name="ID", unique=true, nullable=false, precision=10)
 public Integer getId() {
  return this.id;
 }
 public void setId(Integer id) {
  this.id = id;
 }

 @Basic()
 @Column(name="DESCRIPT", length=255)
 public String getDescript() {
  return this.descript;
 }
 public void setDescript(String descript) {
  this.descript = descript;
 }

 @Basic()
 @Column(name="FULLNAME", length=32)
 public String getFullname() {
  return this.fullname;
 }
 public void setFullname(String fullname) {
  this.fullname = fullname;
 }

 @Basic()
 @Column(name="NAME", unique=true, nullable=false, length=16)
 public String getName() {
  return this.name;
 }
 public void setName(String name) {
  this.name = name;
 }

 public boolean equals(Object other) {
  if (this == other) {
   return true;
  }
  if (!(other instanceof Account)) {
   return false;
  }
  Account castOther = (Account)other;
  return new EqualsBuilder()
   .append(this.getId(), castOther.getId())
   .isEquals();
    }

 public int hashCode() {
  return new HashCodeBuilder()
   .append(getId())
   .toHashCode();
    }

 public String toString() {
  return new ToStringBuilder(this)
   .append("id", getId())
   .toString();
 }
}

My test is to insert 1000 records into the table. The test code is like this:
 private static void insertJPA() throws DAOException, SQLException {
  DAOFactory daoF = new DAOFactory();
  AccountDao accountDao = daoF.getAccountDao();
  System.out.println(new java.util.Date().toString());

  for (int i = 0; i<1000; i++)
  {

   TransactionProxy tran = accountDao.beginTransaction();
   Account newuser = new Account();
   newuser.setName("user" + i);
   //newuser.setFullname("User No. " + i);
   //newuser.setDescript("Common user");
   accountDao.insert(newuser);
   accountDao.commitTransaction(tran);
  }
 }


This test can only finish in about 1min 30sec, equals to 11rec/sec. If
I get rid of the fullname and descript fields from the table. The time
can be shorten to 32sec. But it still be quite slow. I've done the
test with BEA Kodo which is based on OpenJPA. Kodo can insert the 1000
record in 9sec, about 10 times faster than OpenJPA. And I did not do
any optimization for Kodo.

So anybody knows why the performance of OpenJPA is so slow? Or how to
optimize OpenJPA to achieve the performance near Kodo?

Thanks a lot.

Re: Weird Performance Problem

Posted by Werner Punz <we...@gmail.com>.
This definitely looks like a problem of the code itself,
usually inserts with transactions on every insert are bound to be slower
than bulk transactions.
This is the nature of  things. Usually to be able to handle really high 
volume loads many databases support bulk insert operations one way or 
the other.

Also which helps if you cannot live without one transaction per dataset,
try to split the data and push it in multithreaded.
That helps to some extent.

But the quickest fix for now is to make multi insert dataset transactions!


Werner


Pinaki Poddar schrieb:
> Are you are beginning/committing 1000 transactions to insert 1000 instances?
> 
> 
> Chengdong Lu wrote:
>>
>> My test is to insert 1000 records into the table. The test code is like
>> this:
>>  private static void insertJPA() throws DAOException, SQLException {
>>   DAOFactory daoF = new DAOFactory();
>>   AccountDao accountDao = daoF.getAccountDao();
>>   System.out.println(new java.util.Date().toString());
>>
>>   for (int i = 0; i<1000; i++)
>>   {
>>
>>    TransactionProxy tran = accountDao.beginTransaction();
>>    Account newuser = new Account();
>>    newuser.setName("user" + i);
>>    //newuser.setFullname("User No. " + i);
>>    //newuser.setDescript("Common user");
>>    accountDao.insert(newuser);
>>    accountDao.commitTransaction(tran);
>>   }
>>  }
>>
>>
> 


Re: Weird Performance Problem

Posted by kuuldor <ku...@gmail.com>.
Yes. I think it will be reasonable because in the real environment
each inserting may be arosed by different client and be in one
transaction.

2008/1/22, Pinaki Poddar <pp...@apache.org>:
>
> Are you are beginning/committing 1000 transactions to insert 1000 instances?
>
>
> Chengdong Lu wrote:
> >
> >
> > My test is to insert 1000 records into the table. The test code is like
> > this:
> >  private static void insertJPA() throws DAOException, SQLException {
> >   DAOFactory daoF = new DAOFactory();
> >   AccountDao accountDao = daoF.getAccountDao();
> >   System.out.println(new java.util.Date().toString());
> >
> >   for (int i = 0; i<1000; i++)
> >   {
> >
> >    TransactionProxy tran = accountDao.beginTransaction();
> >    Account newuser = new Account();
> >    newuser.setName("user" + i);
> >    //newuser.setFullname("User No. " + i);
> >    //newuser.setDescript("Common user");
> >    accountDao.insert(newuser);
> >    accountDao.commitTransaction(tran);
> >   }
> >  }
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/Weird-Performance-Problem-tp14998594p15003474.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>
>

Re: Weird Performance Problem

Posted by Pinaki Poddar <pp...@apache.org>.
Are you are beginning/committing 1000 transactions to insert 1000 instances?


Chengdong Lu wrote:
> 
> 
> My test is to insert 1000 records into the table. The test code is like
> this:
>  private static void insertJPA() throws DAOException, SQLException {
>   DAOFactory daoF = new DAOFactory();
>   AccountDao accountDao = daoF.getAccountDao();
>   System.out.println(new java.util.Date().toString());
> 
>   for (int i = 0; i<1000; i++)
>   {
> 
>    TransactionProxy tran = accountDao.beginTransaction();
>    Account newuser = new Account();
>    newuser.setName("user" + i);
>    //newuser.setFullname("User No. " + i);
>    //newuser.setDescript("Common user");
>    accountDao.insert(newuser);
>    accountDao.commitTransaction(tran);
>   }
>  }
> 
> 

-- 
View this message in context: http://www.nabble.com/Weird-Performance-Problem-tp14998594p15003474.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Weird Performance Problem

Posted by kuuldor <ku...@gmail.com>.
Hi everybody,
I forgot to mention that the application is running in a web
container, namely Tomcat 5.5. Does that matter?
I've modified the helloJPA example shipped with 1.0.1 to insert 10000
records in the same way in my test, it works fine and the performance
is good. But when I use same entity class in a web application, the
performance drops dramatically. I wonder what's the difference between
two environments? Is that because the transaction is managed by the
container?

2008/1/21, kuuldor <ku...@gmail.com>:
> Hi everybody,
> I'm trying to use OpenJPA in my new project, but when I do some
> experiments I encounter a very low performance in inserting records
> into database.
>