-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: Hibernate vs JDBC. Performance
PostPosted: Thu Jun 07, 2007 11:50 am 
Newbie

Joined: Wed May 30, 2007 6:47 am
Posts: 5
Greetings , at me such problem, I have noticed, that at use Hibernate, data are saved many times more slowly than at use JDBC. I have written an example, which puts in three tables 100, 1000 of objects (does 300, 3000 insert) and here results:
structure of tables:
Timestamp <-------> time_request <------> Request

Test a config.
JDK 1.6
HSQL
Windows Vista

100 objects
Hiberane 631ms
JDBC 7ms

1000 objects
Hiberane 5425ms
JDBC 56ms
As you can see, Hibernate many times more slowly. Whether a question it is possible to achieve more comprehensible results at hibernate.
The test project (the size ~6Mb) it is possible to download>>> http://public.rz.fh-wolfenbuettel.de/~barvenko/HibernateVsJDBC/HibernateVsJDBC.zip<<<, it comprises all necessary, only to start and all. Start BD and GUI to it, is carried out through two *.bat a file laying in a folder lib.

Here so I save.
Code:
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.hibernate.ejb.EntityManagerFactoryImpl;
import test.Request;
import test.RequestTime;
import test.TimeStamp;
public class MainTest {
    private EntityManagerFactory emf;
    private Session entityManager;
    private Transaction tx2;
    private int insert = 1000;
    public MainTest() {
        emf = Persistence.createEntityManagerFactory("test");
        entityManager = (Session) emf.createEntityManager().getDelegate();
        tx2 = entityManager.getTransaction();
        start();
//        saveWithNativeSQL();
    }
    private void start() {
        tx2.begin();
        ArrayList<RequestTime> liste = new ArrayList<RequestTime>();
        for (int i = 0; i < insert; i++) {
            TimeStamp timeStamp = new TimeStamp();
            timeStamp.setDay((byte) (6 + i));
            timeStamp.setHour((byte) (5 + i));
            timeStamp.setMonth((byte) (7 - i));
            Request request = new Request("XMLCON", "198.56.3.255", "wap");
            RequestTime newLink = new RequestTime(666, timeStamp, request);
            liste.add(newLink);
            //        List<RequestTime> criteria = entityManager.createCriteria(RequestTime.class).
            //        add( Restrictions.eq("request", request)).
            //        add(Restrictions.eq("timeStamp", timeStamp)).list();
        }
        long start = System.currentTimeMillis();
        for (RequestTime time : liste) {
            entityManager.save(time);
        }
        tx2.commit();
        entityManager.close();
        System.out.println("Done.\tExecuted time: "
                + (System.currentTimeMillis() - start));
    }
    private void saveWithNativeSQL() {
        try {
            Class.forName("org.hsqldb.jdbcDriver");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            int[] updateCounts = null;
            java.sql.Connection con = DriverManager.getConnection(
                    "jdbc:hsqldb:hsql://localhost/test", "sa","");
            con.setAutoCommit(false);
            long start = System.currentTimeMillis();
            Statement s = con.createStatement();
            for (int i = 1; i < insert; i++) {
                s.addBatch("INSERT INTO Request VALUES (" + i
                        + ",'aaa','aaa','aaa')");
                s.addBatch("INSERT INTO TimeStamp VALUES (" + i + ",5,1,1,1)");
                s.addBatch("INSERT INTO time_request VALUES (" + i + ",5," + i
                        + "," + i + ")");
            }
            updateCounts = s.executeBatch();
            con.commit();
            System.out.println("Done.\tExecuted time: "
                    + (System.currentTimeMillis() - start));
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        new MainTest();
    }
}


So looks my config file


Code:
<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">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>test.TimeStamp</class>
        <class>test.RequestTime</class>
        <class>test.Request</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
            <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost/test" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
        <!--    <property name="hibernate.cache.provider_class"
                value="org.hibernate.cache.EhCacheProvider" />  -->
            <property name="hibernate.connection.username" value="sa" />
        <!--    <property name="hibernate.connection.password" value="" />
            <property name="hibernate.jdbc.batch_size" value="50" /> -->
            <property name="hibernate.cache.use_second_level_cache"
                value="false" />
            <property name="hibernate.hbm2ddl.auto" value="create" />
        <!--    <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.max_fetch_depth" value="3" /> -->
        </properties>
    </persistence-unit>
</persistence>



This is my mapping files
Code:
/**
* (Start,[Via1,Via2,..Vian], Ziel)
*/
package test;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.CollectionOfElements;
import org.hibernate.annotations.IndexColumn;
/**
* @author Unkis
*
*/
@Entity
@Table(name = "Request")
public class Request implements Serializable {
    private long id;
    private Collection timeStamps;
    private String type;
    private String virtServer;
    private String info;
    public Request() {
    }
    public Request(Collection timeStamps, String type, String virtServer,
            String info) {
        super();
        this.timeStamps = timeStamps;
        this.type = type;
        this.virtServer = virtServer;
        this.info = info;
    }
    public Request(String type, String virtServer, String info) {
        super();
        this.type = type;
        this.virtServer = virtServer;
        this.info = info;
    }
    @Id
    @Column(name = "request_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getInfo() {
        return info;
    }
    public void setInfo(String info) {
        this.info = info;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getVirtServer() {
        return virtServer;
    }
    public void setVirtServer(String virtServer) {
        this.virtServer = virtServer;
    }
    @ManyToMany(targetEntity = TimeStamp.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "time_request", joinColumns = @JoinColumn(name = "request_id"), inverseJoinColumns = @JoinColumn(name = "time_id"))
    public Collection getTimeStamps() {
        return timeStamps;
    }
    public void setTimeStamps(Collection locations) {
        this.timeStamps = locations;
    }
}

Code:
package test;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "time_request")
public class RequestTime implements Serializable {
    private long id;
    private Request request;
    private TimeStamp timeStamp;
    private int number;
    public RequestTime() {
        super();
        // TODO Auto-generated constructor stub
    }
    public RequestTime(int number, TimeStamp timeStamps, Request request) {
        super();
        this.request = request;
        this.timeStamp = timeStamps;
        this.number = number;
    }
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    @Basic
    @Column(nullable = false)
    public int getNumber() {
        return number;
    }
    public void setNumber(int number) {
        this.number = number;
    }
    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "time_id", nullable = false, updatable = false)
    public TimeStamp getTimeStamp() {
        return timeStamp;
    }
    public void setTimeStamp(TimeStamp timeStamp) {
        this.timeStamp = timeStamp;
    }
    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "request_id", nullable = false, updatable = false)
    public Request getRequest() {
        return request;
    }
    public void setRequest(Request request) {
        this.request = request;
    }
}



Code:
package test;
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
@Entity
public class TimeStamp implements Serializable {
    //    private Long id;
    /**
     * Id of location
     */
    private Long time_id;
    private Collection resuests;
    private byte hour;
    private byte day;
    private byte month;
    private short year;
    public TimeStamp() {
        super();
        // TODO Auto-generated constructor stub
    }
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "location_id")
    public Long getTime_id() {
        return time_id;
    }
    public void setTime_id(Long location_id) {
        this.time_id = location_id;
    }
    public TimeStamp(Collection resuests, byte hour, byte day, byte month,
            short year) {
        super();
        this.resuests = resuests;
        this.hour = hour;
        this.day = day;
        this.month = month;
        this.year = year;
    }
    public TimeStamp(byte hour, byte day, byte month, short year) {
        super();
        this.hour = hour;
        this.day = day;
        this.month = month;
        this.year = year;
    }
    public byte getDay() {
        return day;
    }
    public void setDay(byte day) {
        this.day = day;
    }
    public byte getHour() {
        return hour;
    }
    public void setHour(byte hour) {
        this.hour = hour;
    }
    public byte getMonth() {
        return month;
    }
    public void setMonth(byte month) {
        this.month = month;
    }
    public short getYear() {
        return year;
    }
    public void setYear(short year) {
        this.year = year;
    }
    @ManyToMany(targetEntity = Request.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "time_request", joinColumns = @JoinColumn(name = "time_id"), inverseJoinColumns = @JoinColumn(name = "request_id"))
    public Collection getResuests() {
        return resuests;
    }
    public void setResuests(Collection resuests) {
        this.resuests = resuests;
    }
}



Last edited by unkis on Thu Jun 07, 2007 1:16 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 07, 2007 12:28 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
You need to understand basic concepts such as "persistence context cache" before you try to benchmark something.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 08, 2007 5:45 am 
Regular
Regular

Joined: Fri May 12, 2006 4:05 am
Posts: 106
Also HSQL-DB as an in-memory-DB strongly emphasizes the hibernate-generated overhead. The weight of this overhead will be much less when using some other DBMS like mysql.
If you check out the benchmark-results on http://polepos.sourceforge.net/results/html/index.html you'll find that hibernate/HSQL is factor 100 slower than jdbc/HSQL - about the same results you got. But when looking at hibernate/mysql compared to jdbc/mysql the difference is only factor 3 since database-access is much, much slower on this system. And in real-life applications hibernates strength lies in avoiding these really slow database-accesses.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 08, 2007 8:47 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
That only means that the Poleposition benchmark is the same nonsense and broken code as this one. It really is.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 08, 2007 9:39 am 
Regular
Regular

Joined: Fri May 12, 2006 4:05 am
Posts: 106
I just wanted to stress that measuring these artificial situations with hsql is even more nonsense than measuring with a real-world DBMS. Best and only thing is measuring real-world applications with real-world DBMS and you'll see where hibernaet ends up then. If it's well conifugerd I'm sure it will easily beat pure jdbc regarding performance-aspects.
I only mentioned PolePosition since it had those numbers readily available. The results surely don't count much for themselves since some of those tests are pretty good at hiding hibernate's advantages....


Top
 Profile  
 
 Post subject: Hibernate vs JDBC. Performance
PostPosted: Fri Jun 08, 2007 9:43 am 
Newbie

Joined: Fri Jun 08, 2007 9:26 am
Posts: 3
I think that there is a real problem here that should be addressed.
I am also facing this problem when saving a large graph of object
(this time against oracle) - it takes really really long time.

I have even profiled it and saw real problems -
also take a look at http://opensource.atlassian.com/projects/hibernate/browse/HHH-2272.

I think you should guide\tip the users here on how solving the problem rather then ignoring them or say that their benchmark is broken(but this is my opinion).


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 08, 2007 9:57 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
We have done that in the past, I see no reason to repeat "read the most basic documentation" over and over again. We simply don't have the time to debug whatever microbenchmarks somebody writes.

http://www.hibernate.org/157.html

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 08, 2007 10:02 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Note that I'm not saying that we don't take performance patches and profiled testcases seriously, we certainly do.

However, there is a world of difference between the code shown here and a profiled testcase that shows unnecessary collection iteration somewhere and a way to improve that. This will be queued accordingly in the developers TODO list - because saving 50.000 instances is a rare case and very likely completely synthetic, it is not the most important case.

I don't think anybody wants the Hibernate devs to spend time debugging microbenchmarks instead, right?

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject: Topic: Hibernate vs JDBC. Performance
PostPosted: Fri Jun 08, 2007 10:38 am 
Newbie

Joined: Fri Jun 08, 2007 9:26 am
Posts: 3
I see your point - however not like other cases - there is a real issue here,
even backed by a JIRA Task (HHH-2272).
I think that this issue has to be taken care - because the problem is pure in Hibernate implementation.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.