I just did some performance tests to compare query performance of Hibernate vs a very well-known leading JDO solution. Here is the code. Note that I don't claim I had the JDO solution configured perfectly, there may be settings I don't know about. (However, I did not do anything exotic to Hibernate either.)
Code:
public static void main(String[] args) {
PersistenceManagerFactory pmf = [CENSORED!];
SessionFactory sf = new Configuration()
.addClass(Foo.class)
.buildSessionFactory();
System.out.println("5000 rows");
for ( int j=0; j<5; j++ ) {
long hb = 0;
long hbstart = System.currentTimeMillis();
for ( int i=0; i<30; i++ ) {
Session s = sf.openSession();
s.setFlushMode(FlushMode.NEVER);
Transaction t = s.beginTransaction();
long ht = System.currentTimeMillis();
List result2 = s.createQuery("from Foo")
//.setReadOnly(true)
.list();
hb += System.currentTimeMillis() - ht;
t.commit();
s.close();
}
long hbtotal = System.currentTimeMillis() - hbstart;
System.out.println("Hibernate: queries=" + hb + ", total=" + hbtotal);
long jodo = 0;
long jdstart = System.currentTimeMillis();
for ( int i=0; i<30; i++ ) {
PersistenceManager pm = pmf.getPersistenceManager();
pm.currentTransaction().begin();
long jt = System.currentTimeMillis();
Object result = pm.newQuery(Foo.class).execute();
jodo += System.currentTimeMillis() - jt ;
pm.currentTransaction().commit();
pm.close();
}
long jdtotal = System.currentTimeMillis() - jdstart;
System.out.println("Brand X: queries=" + jodo + ", total=" + jdtotal);
}
System.out.println("500 rows");
for ( int j=0; j<5; j++ ) {
long hb = 0;
long hbstart = System.currentTimeMillis();
for ( int i=0; i<200; i++ ) {
Session s = sf.openSession();
s.setFlushMode(FlushMode.NEVER);
Transaction t = s.beginTransaction();
long ht = System.currentTimeMillis();
List result2 = s.createQuery("from Foo foo where foo.id<500")
.setReadOnly(true)
.list();
hb += System.currentTimeMillis() - ht;
t.commit();
s.close();
}
long hbtotal = System.currentTimeMillis() - hbstart;
System.out.println("Hibernate: queries=" + hb + ", total=" + hbtotal);
long jodo = 0;
long jdstart = System.currentTimeMillis();
for ( int i=0; i<200; i++ ) {
PersistenceManager pm = pmf.getPersistenceManager();
pm.currentTransaction().begin();
long jt = System.currentTimeMillis();
Query q = pm.newQuery(Foo.class);
q.setFilter("id<500");
Object result = q.execute();
jodo += System.currentTimeMillis() - jt ;
pm.currentTransaction().commit();
pm.close();
}
long jdtotal = System.currentTimeMillis() - jdstart;
System.out.println("Brand X: queries=" + jodo + ", total=" + jdtotal);
}
The output:
5000 rows
Hibernate: queries=5067, total=5157
Brand X: queries=5629, total=5869
Hibernate: queries=3765, total=3825
Brand X: queries=4937, total=4957
Hibernate: queries=3746, total=3796
Brand X: queries=4807, total=4807
Hibernate: queries=3985, total=4055
Brand X: queries=4857, total=4857
Hibernate: queries=3735, total=3796
Brand X: queries=4827, total=4837
500 rows
Hibernate: queries=1722, total=1913
Brand X: queries=2413, total=2483
Hibernate: queries=1703, total=1853
Brand X: queries=2363, total=2433
Hibernate: queries=1723, total=1843
Brand X: queries=2554, total=2594
Hibernate: queries=1532, total=1682
Brand X: queries=2524, total=2584
Hibernate: queries=1552, total=1672
Brand X: queries=2524, total=2574
I am NOT going to claim that either solution is faster than the other, merely showing that performance is very comparable. If anything, HB has a small edge in this particular very oversimplified test.