quality@glassfish.java.net

Re: Performance JPA?

From: Richard Kolb <rjdkolb_at_gmail.com>
Date: Fri, 4 Mar 2011 13:34:10 +0200

Hi Matthias

Another thing to remember is cache.
You should proably have a second bunch of tests that do the queries twice.
JPA will cache , so the second run should be much faster.

I am guessing this is the other part of the over head.

Don't forget to implement equals and hashCode on Customer to make JPA happy.
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Customer other = (Customer) obj;
        if (this.id != other.id) {
            return false;
        }
        if ((this.name == null) ? (other.name != null) : !this.name.equals(
other.name)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 89 * hash + this.id;
        hash = 89 * hash + (this.name != null ? this.name.hashCode() : 0);
        return hash;
    }

regards
Richard

On 4 March 2011 11:32, Matthias Fraass <matthias.fraass_at_tricoder.net> wrote:

> Hi Edward,
>
> thank you for your suggestions. You're right: the comparison wasn't fair as
> I didn't iterate through some result sets.
> I changed that now and the JDBC query did get a lot slower. It's still much
> faster than the other two.
>
> * JDBC: 4.7s
> * JPA: ~7.2s
> * EJB: ~7.5s
>
> To give you some background information: we had a batch process which did
> run for about 1h with JDBC. We changed it to nativeQueries without doing any
> architectural or proccessual changes and it ran for 3 days...
> So I was trying to break down the performance problem into a simple
> example, which I posted here.
> Of course it could be that we're doing something incredibly wrong, but I'm
> not seeing it yet.
>
> I added some comments on the test methods to show what I was expecting from
> it.
> As I wrote in my first post, I was expecting the nativeQuery to be almost
> as fast as the JDBC query. As I've learned now there is a O/R mapping going
> on. Maybe the results above will get worse for JPA when the result set not
> only consists of two rows (which is the case in our real application).
>
> Please anyone have a look at this new version. Your thoughts about it are
> very welcome!
>
> Best regards,
>
> Matthias
>
>
> Am 03.03.2011 15:45, schrieb Edward Bratt:
>
>> We had a look at your tests and can offer the following:
>>
>> * doQueryJDBC() only executes the query against the database. The
>> returned result is not processed
>> * doQueryJPA() calls queryJPA.getResultList() which not only
>> executes the query but traverse the result set and constructs the
>> customer objects.
>>
>> Try modifying doQueryJDBC() also to traverse the result set and
>> construct Customer object for a correct comparison and let us know how
>> that stacks up.
>>
>> I can't comment on Hibernate.
>>
>> -- Ed
>>
>> On 3/3/2011 1:22 AM, Richard Kolb wrote:
>>
>>> Hi Matthias
>>>
>>> On 2 March 2011 19:51, Matthias Fraass <matthias.fraass_at_tricoder.net
>>> <mailto:matthias.fraass_at_tricoder.net>> wrote:
>>>
>>> long time no see :).
>>>
>>>
>>> :)
>>>
>>>
>>> First, I can tell you that our Weblogic -> Glassfish migration is
>>> on good progress! We already have switch several servers and there
>>> are more to come!
>>>
>>> I was struggling with maintaining batch process the other day and
>>> was wondering whether it would be more coder friendly using JPA's
>>> native queries.
>>> I was quite shocked about the performance hit we got: Mind you,
>>> we're NOT using full-fledged Entity beans: just plain SQL! The
>>> performance still was about x4 - x10 worse than using plain JDBC
>>> and PreparedStatements!
>>>
>>> As the java.net <http://java.net> forums seem to be quite dead, I
>>>
>>> thought it'd be a good idea to talk to you folks.
>>>
>>> So I put up a little test to verify it. You'll find it attached.
>>> If you have Maven2, it should run immediately (after downloading
>>> glassfish embedded 3.1, though...).
>>> It's simple: first, it creates a table "customer" and inserts 1000
>>> rows. Then it will do "SELECT * from customer" in three different
>>> ways:
>>>
>>> * via JDBC -> will take under 1s (including call of the session bean)
>>> * via JPA's createNativeQuery -> will take about 4-7 seconds
>>> * via EJB-QL -> will take about 4-7 seconds
>>>
>>> It's just doing the select - no parsing of the resultset at all.
>>> I know that it is a very rough test but it does it's purpose:
>>> showing that JPA is much slower than JDBC.
>>>
>>> Don't bother about the Derby database (you can start it via
>>> glassfish\javadb\bin\startNetworkServer). I can verify this using
>>> a remote Oracle 10g database on HP-UX.
>>>
>>> How come this is so slow? There's no O/R-Mapping involved and the
>>> queries are prepared before calling it - what's taking it so long?
>>> I had big hopes in JPA's native queries for breaking the last
>>> plain JDBC bastion!
>>>
>>> Or am I missing some basic thing?
>>>
>>>
>>> This is a topic that interest me as well.
>>> We are developing a key system where performance is everything.
>>> Slow queries actually get SLA violations.
>>>
>>> We are using Hibernate 3 native queries to query a HP Non-stop database.
>>>
>>> We were also wondering why JPA Hibernate was so much slower than
>>> straight JDBC (yuck)
>>>
>>> Busy downloading your sample.
>>> We have a license for JProfiler, perhaps I can profile it.
>>> regards
>>> Richard
>>>
>>>
>>>
>>>
>>>
>