I was thinking to switch to OpenJPA from Spring JDBC, just recently run
a very simple test with 2 classes, SQL insert basically, the difference
between plain JDBC and OpenJPA is more than 7 times!
Why such poor performance? Below is my sample code and results, I used
Enhancer as JVM argument, actually without it JPA result was almost
twice faster!
public static void main(String[] args) {
Bill bill = new Bill();
int id = new JVMRandom().nextInt(Integer.MAX_VALUE);
bill.setId(id);
bill.setCreated(new Date());
bill.setPurchaseid(501253634);
bill.setStatus(1);
// System.out.println("bill id=" + id);
Product prod = new Product();
prod.setId(1);
BillProduct bp = new BillProduct();
bp.setBillid(bill);
bp.setId(new JVMRandom().nextInt(Integer.MAX_VALUE));
bp.setProductid(prod);
StopWatch sw = new StopWatch();
try {
Class.forName("org.postgresql.Driver");
String url =
"jdbc:postgresql://localhost/mydb?user=admin&password=admin";
Connection conn = DriverManager.getConnection(url);
conn.setAutoCommit(false);
// System.out.println("bill id=" + id);
sw.start();
PreparedStatement pstm = conn
.prepareStatement("insert into bill(id, status,
purchaseid, created) values (?, ?, ?, ?)");
pstm.setInt(1, bill.getId());
pstm.setInt(2, bill.getStatus());
pstm.setInt(3, 501253634);
pstm.setDate(4, new java.sql.Date(System.currentTimeMillis()));
pstm.executeUpdate();
pstm.close();
pstm = conn
.prepareStatement("insert into bill_product(id,
productid, billid) values (?, ?, ?)");
pstm.setInt(1, new JVMRandom().nextInt(Integer.MAX_VALUE));
pstm.setInt(2, 1);
pstm.setInt(3, bill.getId());
pstm.executeUpdate();
pstm.close();
conn.commit();
sw.stop();
System.out.println("jdbc time=" + sw.getTime());
conn.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sw.reset();
//openjpa
id = new JVMRandom().nextInt(Integer.MAX_VALUE);
bill.setId(id);
bp.setId(new JVMRandom().nextInt(Integer.MAX_VALUE));
// persist
EntityManagerFactory emf = Persistence
.createEntityManagerFactory("testjpa");
EntityManager em = emf.createEntityManager();
sw.start();
em.getTransaction().begin();
em.persist(bill);
em.flush();
em.persist(bp);
em.getTransaction().commit();
sw.stop();
System.out.println("openjpa time=" + sw.getTime());
em.close();
}
*Console output: *
jdbc time=78
93 testjpa INFO [main] openjpa.Runtime - Starting OpenJPA 1.2.0
203 testjpa INFO [main] openjpa.jdbc.JDBC - Using dictionary class
"org.apache.openjpa.jdbc.sql.PostgresDictionary".
openjpa time=547