‏הצגת רשומות עם תוויות Hibernate. הצג את כל הרשומות
‏הצגת רשומות עם תוויות Hibernate. הצג את כל הרשומות

How to debug BatchUpdateException

In order to work efficiency against database we aggregate some statements together in a batch and run them all together. This save db roundtrips  However when there is an error in one of the statement its difficult to figure out what is the root cause, since we will get a fog error like this:

Caused by: java.sql.BatchUpdateException: failed batch

In order to find the problematic statement you should change the jdbc batch property to 0, so jdbc will run each statement individually.

If you use hibernate set "hibernate.jdbc.batch_size" to 0.


Hibernate best FAQ

I recommend this hibernate QA post  good for both new and advanced hibernate users.
In additional you will find the hibernate FAQ very useful. It catalogue by advanced/new FAQ.

Hibernate second level cache - The Timestamp region

If you are not familiar with Hibernate second level cache internal implementation than I suggest that you will read the following link before continue reading.The follwoing link should do you introduction with Hibernate cache regions, Hibernate cache associations, How Hibernate store Objects in cache.
http://www.javalobby.org/java/forums/t48846.html

UpdateTimestamsCache region is not cover in the previoues link , so we are going to duscess it in this post.
UpdateTimestamsCache store the last time that a table was written. This data is imporatnt in order to prevent stale data.

Details on the UpdateTimestamsCache regioncan be found in the following link -  http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/11/09/first-and-second-level-caching-in-nhibernate.aspx .

Now, when we come to actually using the cache, we should be aware to few things:
1.         Each session is associated with a timestamp on creation.
2.         Every time we put query results in the cache, the timestamp of the executing session is recorded.

3.         The timestamp cache is updated whenever a table is written to, but in a tricky sort of way:
When we perform the actual writing, we write a value that is somewhere in the future to the cache. So all queries that hit the cache now will not find it, and then hit the DB to get the new data. Since we are in the middle of transaction, they would wait until we finish the transaction. If we are using low isolation level, and another thread / machine attempts to put the old results back in the cache, it wouldn't hold, because the update timestamp is into the future.

When we perform the commit on the transaction, we update the timestamp cache with the current value.

Now, let us think about the meaning of this, shall we?

If a session has performed an update to a table, committed the transaction and then executed a cache query, it is not valid for the cache. That is because the timestamp written to the update cache is the transaction commit timestamp, while the query timestamp is the session's timestamp, which obviously comes earlier.

The update timestamp cache is not updated until you commit the transaction! This is to ensure that you will not read "uncommitted values" from the cache.

Please note that if you open a session with your own connection, it will not be able to put anything in the cache (all its cached queries will have an invalid timestamp!)

In general, those are not things that you need to concern yourself with, but I spent some time today just trying to get tests for the second level caching working, and it took me time to realize that in the tests I didn't used transactions and I used the same session for querying as for performing the updates.

Hibernate support for horizontal partitioning


Problem:
Same model need to persist to multiple databases.
For example - SAAS

There are some strategies how to handle SAAS persistency.You can store all customers' data in the same tables, so you have single table for all customers,Or you can create different scheme (or database) for each customer.
Any solution has its own advantages and disadvantages.

A lot of companies chose the second approach (scheme for each customer) and have a problem to integrate it with hibernate.

Session factory is per persistence physical location, so even that this is the same model and the only difference is the connection parameters you need to create new session factory.
Session factory is an expensive object (creation time and size), so create session factory for each customer can kill the application.

This kind of problems Hibernate shard, a new open source of Hibernate come to solve.
http://docs.jboss.org/hibernate/stable/shards/reference/en/html_single/
Here is the preface:
You can't always put all your relational data in a single relational database. Sometimes you simply have too much data. Sometimes you have a distributed deployment architecture (network latency between California and India might be too high to have a single database). There might even be non-technical reasons (a potential customer simply won't do the deal unless her company's data lives in its own db instance). Whatever your reasons, talking to multiple relational databases inevitably complicates the development of your application. Hibernate Shards is a framework that is designed to encapsulate and minimize this complexity by adding support forhorizontal partitioning on top of Hibernate Core.
And this is how is builds:
1     public SessionFactory createSessionFactory() {
2         Configuration prototypeConfig = new Configuration().configure("shard0.hibernate.cfg.xml");
3         prototypeConfig.addResource("weather.hbm.xml");
4         List shardConfigs = new ArrayList();
5         shardConfigs.add(buildShardConfig("shard0.hibernate.cfg.xml"));
6         shardConfigs.add(buildShardConfig("shard1.hibernate.cfg.xml"));
7         shardConfigs.add(buildShardConfig("shard2.hibernate.cfg.xml"));
8         ShardStrategyFactory shardStrategyFactory = buildShardStrategyFactory();
9         ShardedConfiguration shardedConfig = new ShardedConfiguration(
10            prototypeConfig,
11            shardConfigs,
12            shardStrategyFactory);
13        return shardedConfig.buildShardedSessionFactory();
14    }
15
16    ShardStrategyFactory buildShardStrategyFactory() {
17        ShardStrategyFactory shardStrategyFactory = new ShardStrategyFactory() {
18            public ShardStrategy newShardStrategy(List shardIds) {
19                RoundRobinShardLoadBalancer loadBalancer = new RoundRobinShardLoadBalancer(shardIds);
20                ShardSelectionStrategy pss = new RoundRobinShardSelectionStrategy(loadBalancer);
21                ShardResolutionStrategy prs = new AllShardsShardResolutionStrategy(shardIds);
22                ShardAccessStrategy pas = new SequentialShardAccessStrategy();
23                return new ShardStrategyImpl(pss, prs, pas);
24            }
25        };
26        return shardStrategyFactory;
27    }
28
29    ShardConfiguration buildShardConfig(String configFile) {
30        Configuration config = new Configuration().configure(configFile);
31        return new ConfigurationToShardConfigurationAdapter(config);
32    }
  


As you can see from the above createSessionFactory build from multiple cfgs file, so we have one session factory for all configurations.Hibernate shard come with a lot of power to control the persistency partition strategy. You can save to a partition based on ids or parallel or round robin…

For more info:
http://www.infoq.com/presentations/Scaling-Hibernate-Emmanuel-Bernard-Max-Ross

Hibernate – Join by none primary key columns


In a good database design the references (foreign keys) are based on the primary key.

Hibernate assume that, so by default hibernate will do the join based on the entity id (primary key).


 

When you write join in SQL you define the join keys.

For example:

Select * from Customers

Left join Products ON Customers.CustomerId = Products.FkCustomerId


 

In hibernate you don't need to define the join keys (assume join by primary key), so the HQL will look like this:

From Customers C left Join C.Products


 

Hibernate will use the definition of the one-to-many to figure out the column in the Product table and it will join it with the id field of the Customer.


 

What about cases when the join is not based on the CustomerId?

Suppose we have a legacy database where the product join with the customer is based on the customer externalid and not on the customer pk, how we tell hibernate to join on customer external id and not by customer pk?


 

The solution is pretty simple - we use in property-ref.

<set name="Products" table="Products" fetch="select">

    <key column="FkCustomerexternalId" property-ref="CustomerExternalId" />

    <one-to-many class="Product" />

</set>

The column - 'FkCustomerId' is the foreign key in the Products table.

The property ref 'customerExternalId' is the name of the field (not column) in the Customer Pojo.


 

Let's make it more complex:

What if the join is by multiple fields?

Suppose the relation is based on two columns - CustomExternalId and CustomerName how do we tell hibernate to the join based on the two columns?

During my Google search for a solution I encounter in the following link:

https://forum.hibernate.org/viewtopic.php?p=2315103


 


 

The solution suggested by one of the expert is to group the keys properties into properties section, like this:

<properties name="keysNeededByB">

<property name="column1" column="C1" insert="false" update="false"/>

<property name="column2" column="C2" insert="false" update="false"/>

<property name="column3" column="C3" insert="false" update="false"/>

</properties>


 

<bag name="relatedMappings">

<key property-ref="keysNeededByB"/>

<one-to-many class="B"/>

</bag>


 

But, unfortunately all suggestions weren't work for me.

My work solution:

<component name="CustomerKey" class="CustomerKey">

<property name="CustomerexternalId" column="CustomerexternalId" />

<property name="CustomerName" column="CustomerName" />

</component>


 

<set name="Products" lazy="true">

<key property-ref="CustomerKey">

<!-- this is the column names in the product table -->

    <column name="CustomerExternalId" />

    <column name="CustomerName" />

</key>

<one-to-many class="Product" />

</set>


 

Single model - no to presentation model. (DTOs are evil)


How many models do you have in your application?
In a lot application the answer is -3, one for each layer (presentation, business, dal)
In this case each lays need to maintain constraint, adapters, query translation and maintain.



Today, In the POJO revolution when we each layer can handle POJO and don't need a specific class types any more (no need in extends stateless bean, special dal classes ....) we can build a one single POJO model and bypass it between the layers. We don't need any more to maintain constraints, adapters... in each layer.



But still a lot of application want to hide the hibernate model by additional model above it.
By mistake they call it DTO's but the definition is not correct.
The DTO pattern is a pattern that uses in order to solve a case when we need to combine data from some entities. In this case instead of return all entities we use the DTO pattern and created some kind of view (we might also create a view in the underline) on these entities . this view is DTO.
The dto pattern should be avoided as much as possible and I will explain why in another post, but it's still relevant and in some cases it should use in order to avoid loading a lot of entities or to avoid from expose the collection process to the client of this API.


ORM give you the abstraction on the DB layer you shouldn't add another layer to abstract the DB.
ORM can give you all the solution you need in order to solve the DB - Object oriented mismatch and gap between the persistence to the Model.
Adding new layer in the application is height costing for maintains adapters...
You have difficulty to implementing searching, sorting and etc on any object which is not a real model entity.
Exposing direct the model simpler these features.


As I explained above a lot used the term DTO to describe model layer above the ORM layer so in a lot of articles the term DTOs are evil is used in order to describe the general idea of using in additional layer above the entities and not as a specific case solution.
Ask Google for the term - "DTOs are evil" will return a lot of results.
Let's try to explore some of them and some more resources.
In the top of the Google result for "DTOs are evil" we will find adam-bien site with good explanation about the evil in dto:
DTOs aren't dead. The opposite is true. In certain situations, they become the necessary tool or workaround to solve a particular problem….
It is perfect valid to introduce a dedicated DTO to adapt an incompatible domain layer. It is much better, than changing the domain layer to the needs of a particular client …
On the other hand considering a dedicated DTO layer as an investment, rarely pays off and often lead to over-engineered and bloated architectures. At the beginning the DTOs will be identical to your domain layer - without any impedance mismatch. If you are "lucky", you will get few differences over the time. Especially with lightweight platforms like Java EE 6, the introduction of a DTO is a bottom-up, rather than top-down approach. Exactly like it is the case with DAOs.
(For more see - http://www.adam-bien.com/roller/abien/entry/how_evil_are_actually_data )


Another good reference is Rob Harrop's and Jan Machacek's Pro Spring (Chapter 11):
"Honestly, we cannot think of a reason you would want to do this; in our eyes, it seems that this practice has sprung up out of confusion on how certain J2EE patterns should be used."


You will find another interesting discussion for this issue in the following forum – (http://forum.springsource.org/archive/index.php/t-27716.html )
Some good points there:
"In addition, Christian Bauer and Gavin King explore the issue in Chapter 8 of their Hibernate in Action (http://www.amazon.com/gp/product/193239415X/sr=1-1/qid=1155735659/ref=pd_bbs_1/103-9127259-7133451?ie=UTF8&s=books). They note that the data transfer pattern was invented because fine-grained remote access to entity beans was too slow and entity beans were not serializable."

"In the sample applications I have seen, it looks like people have avoided creating data transfer objects. You didn't really give any application-specific reasons for wanting to use data transfer objects, so I would default to using the domain objects directly and saving yourself from the code duplication and all the work to convert to and from the domain objects."

"If the domain model changed, then it is highly likely that the web tier would have to change anyway.
I think there *are* good reasons and situations in which that loose coupling is beneficial, but they are the exception, rather than the rule. After all, the purpose of most web apps is to interrogate the middle tier; they *are* coupled by definition.

If you need to introduce an adapter between the web tier and the middle tier, then you can always do that as and when you need it, but until then just use the POJOs in the domain model."


And if you have some time visit here:
https://forum.hibernate.org/viewtopic.php?f=1&amp;t=928244&amp;sid=c6565b58c62b0eeee2980b7c2b61ee59&amp;start=30


A good summary of the cons and pros can be found
http://blog.xebia.com/2009/05/11/jpa-implementation-patterns-service-facades-and-data-transfers-objects/
Pros and cons of DTO's
Of course it would be silly to say you should always use DTO's in your architecture. As always it depends.   To allow you to make up your own mind, I will list a number of pros and cons of using DTO's:
  1. Con: DTO's cause code duplication. This is especially the case when your DTO's have exactly the same fields as your domain objects, and even more so when they both have getters and setters for those fields. But having DTO's in your architecture allows you to get rid of the getters and setters in your domain objects.
  2. Con: DTO's require you to write boilerplate code to copy properties back and forth. Some people have suggested using a Java Bean mapper framework such as Dozer, Apache Commons BeanUtils, or the Spring Framework's BeanUtils class, but that requires you add getters and setters to your beans and we just decided we did not want to do that anymore!
  3. Pro/Con: DTO's make it impossible to use EntityManger.merge to copy their state to your persistent objects. Instead you'll have to apply the DIY merge pattern as described in my blog on saving (detached) entities. Of course forcing you to do something a particular way, and one that is not 100% satisfying, is not really an advantage. But at least the DTO and the DIY merge work well together.
  4. Pro: DTO's ensure you are not hit by unexpected lazy loading problems in your presentation layer. Or in the case of remote invocations they protect you from lazy loading problems when serializing for transport or, even stranger, on the client.
  5. Pro: The DTO pattern forces you to think about the interface of your application. You can make your DTO's richer than your plain domain objects, e.g. by adding security information to them. Or you can group information from multiple domain objects into one DTO to make the interface easier to use.

Benchmark in general and hibernate benchmark in more details

 Few weeks ago I was asked about Hibernate overhead compared to using direct SQL/JDBC.
The questioner expected to get a numeric answer, which will help him decide between the two. Unfortunately there is no short answer. During this post I will try to cover benchmark concept in general and Hibernate benchmark in particular.


Benchmark in general:

There is a saying that is attributed to Benjamin Disraeli (1804-1881) :
I will focus on the third kind - statistics. 

Few years ago benchmarks was very popular, but today people realize that test results are affected by dozen of parameters such as JVM flags, the number of cores, the hard disk drive , and others. Also, each framework reaches its best on a specific distinguished scenario when running on a specific environment. Eventually the popularity of benchmarks went down. Once in while I encounter benchmarks which demonstrate results of more than 1000% gap between different frameworks, and then, the gap vanish by only changing a single factor like heap size. Furthermore, some frameworks specialize in complex model, while other, in flat model. The conclusion is that the same test case will not bring the best from all frameworks. For those reasons and others, it’s very easy to create misleading benchmarks.

Should benchmark be the leading factor?

The short answer - No.
The fact that framework A is three times faster than framework B is not a guaranty to get the same results in our application.
There could be couples of reasons for that:
1. The benchmark didn’t use cache and in our application we use in cache.
2. It could be that in our application framework A contributes only one percent of the time, thus, replacing framework A for another that work three times faster will have negligible impact to our application performance.
3. It could be that framework B gains its performance speed by creating lots of objects, thus, in case our application suffers from frequent GC or has limited memory,  integrating framework B in our application instead of framework A will reduce performance.



Summary of the problem so far:

1. There are endless test cases; each of them can lead to different result.
2. Each framework need different configuration in order to get the best of it. Furthermore, different test cases scenarios will need different configurations for given framework in order to get the best of it.
3. Faster benchmark doesn’t mean our application will be faster.
4. Speed is not the only factor.

Benchmark and hibernate:

Hibernate performance can be affected by dozens factors, such as memory, DB; local or remote DB, the model complexity and etc’
Database is ranked as one of the main reasons for bottleneck. Hibernate is working with a Database. This brings Hibernate to be a popular player in application performance discussion.
Most of the time (almost 100%), Hibernate development team gets angry when a new post on hibernate performance pop-up. They respond that the benchmark that was performed was not written well. Examples for that:
Look on Gavin King response there:
“Carl, nobody gets upset about competition, people get upset over FUD benchmarks.

Take it offline, guys.”
The guy who post the above didn’t take hibernate unpleasant response for granted and published an angry post on hibernate performance and unpleasant response in his blog:
“I posted some questions to the Hibernate forum to validate the approach I had taken and I received the rather terse and unhelpful reply “This is called 'A useless micro benchmark' and has been addressed a thousand times.” from a member of the Hibernate team. I did some reading of the Hibernate Performance FAQ and found some interesting statements in there, such as "We claim that Hibernate performs well" and "Many people try to benchmark Hibernate. All public benchmarks we have seen so far had (and most still have) serious flaws.” It almost seems like it is taboo to question Hibernate performance. I don't understand this defensive stance since most developers would recognize that there is a tradeoff between ease of use and performance.”


So, where is the truth - what is the overhead of using Hibernate?

If you read the post so far you should already know that you will not get a simple numeric answer from me. As Explained above, it depends on a many factors.
So how should one decide if to use Hibernate or not?
The simple answer - if its work for others it will probably work for you.
This answer is not a silver bullet because small differences between applications can cause a huge performance impact, however if your application has a mainstream common behavior, like other applications which use Hibernate, then it will probably work for you too.

As a child I did stupid things many times (I didn’t rehabilitate from this habit). When the word came to my dad, that I did something stupid, he used to ask me – “why did you do this?” and I always had the same answer – “I did this because everyone else did”. Then my father used to reply – "what if everyone was jumping off the roof, would you also do did this?”
The analogy is that the fact that everyone uses hibernate is not strong and sufficient case, but this case has some power. If everyone succeeds in using it, then the burden on proving there are problems in Hibernate passes to you. In most cases you will find out that the problems which popped up came from using the framework incorrectly, and not because Hibernate has problems or performance issues.

Stop blathering and give as some numeric answers

Hibernate FAQ states that there is 10% overhead on using this framework:
http://simoes.org/docs/hibernate-2.1/15.html “We claim that Hibernate performs well, in the sense that its performance is limited by the underlying JDBC driver / relational database combination. (Generally the overhead is much less than 10% of the JDBC calls.)”
“Most of the performance problems we have come up against have been solved not by code optimizations, but by adding new functionality. It turns out that the overhead of Hibernate itself, compared to equivalent direct SQL/JDBC, is almost always so small as to be irrelevant. So we concentrate our effort upon producing more efficient SQL/JDBC. The bottleneck is always the database itself.”

However, all over the web you will find people saying they think there is a greater overhead, which means less performance.  The truth is that most of them did not ran any benchmark test. Some, ran benchmark, but did run them well. They did not take into consideration that a good benchmark test should clear the DB cache, warm the JVM and etc’
Following the link to a post about consideration to be taken with JVM level, in order to create a good benchmark:
I chose to cover here three benchmarks.

The Ugly:

The ugly benchmark is so ugly that it caused Gavin King to be angry and even to invest time and publish a post on this benchmark. Why is it ugly?
A company named Software Tree released a new version of their ORM product, JDX. In addition they came equipped with STORM, the Tree Object/Relational Mapping Benchmark Software.
Since this is a commercial product I expect them to invest a minimal time and effort before they publish benchmarks, but they didn’t do that. Instead,  the code they wrote for benchmarking Hibernate was worse than a beginner/new comer to hibernate code.
It worth to look and see why Gavin doesn’t like benchmarks:
“Now, having spent a fair amount of time performance profiling database access technologies, I knew for a fact that these kinds of benchmarks are usually completely misleading. With such small datasets, accessed repeatedly, the database is able to completely cache results in memory; the benchmark never actually involves any real disk access (watch your hard drive while STORM runs). We never get to see what happens once the dataset is too large to fit in memory, or is being updated by another transaction. We never get to see what happens with the database is under load. In fact, this benchmark involves no concurrency at all! We never get to see any joins or any of those other things that happen in realistic use cases. Furthermore, these kinds of benchmarks are often run against a local database, which gives results that are absolutely meaningless once the database is installed on a physically separate machine. What this means is that
1. Any overhead added by the ORM is massively exaggerated compared to production scenarios
2. We cannot observe how the system scales

The interesting part of ORM performance comes when you start to investigate caching and especially the flexibility of association fetching strategies. In a nontrivial object model with associations, it is usually association fetching that limits performance. ORM tools must provide flexible ways of choosing between Lazy fetching plus process-level caching and
Eager fetching using outer joins.”

Gavin take their benchmark and play a little with it.
They started with 2 minute to Hibernate and 12 sec to JDX.
After changing some basic hibernate usage, the time has been reduced to 21 sec.
JDX doesn’t use in prepared statement which means that if you run small tests the benefit can be better. Gavin plays a little with the test and in some cases Hibernate wins JDX and in another the results are the same.
The above post is recommended for reading.

The Interesting:

Another interesting benchmark came from Italy.
Why is interesting? Because, unlike other benchmarks that compare the time that take for each tool to do X , this one compares the productivity of the frameworks for a given time (30 minutes).In additional unlike others that compare flat simple single class in almost empty DB here is uses  MySql sample database. The employee sample database e was developed by Patrick Crews and Giuseppe Maxia and provides a combination of a large base of data (approximately 160MB) spread over six separate tables and consisting of 4 million records in total. This benchmark comparea different JPA implementations, but unfortunately it didn’t add JDBC to this benchmark.
Results
These were the results of the tests per JPA implementation library. Notice that the time frame is fixed; 30 minutes for running each framework, and here is what each framework succeed to do in 30 minutes.
Number of queries+inserts executed
Number of queries executed
Number of inserts executed
Max mem occupied during the test(Mb)
Mem occupied after the test(Mb)
OpenJPA
3928
3530
398
96
61
Hibernate
12687
3080
9607
130
79
Toplink Essentials
5720
3740
1980
55
25
Eclipselink
5874
3735
2139
57
25

Red represent bad.
Bold represent top result.
Ps – Hibernate consume large memory but it did more work than others, so it’s reasonable.
First we need to grateful for the investment, but still this benchmark suffers from several benchmarks issues. It cleans the DB and avoid from basic problems, but have other issues that need to take into consideration when you do benchmark.  The guy did that benchmark gets a lot of response, few of them deal with the way he did the benchmark. He also publishes the reference in server side and gets a lot of response there.
Its worth to take a look on   John Stecher interesting comment before jumping to conclusions:
http://www.theserverside.com/news/thread.tss?thread_id=53142

.Net and Java

This benchmark is for both .Net and Java include Linq and Hibernate
The test suite consists of:
A simple query to return 1000 records.
A simple query to return 1 record.
A simple query to insert 1 record

His Conclusion:
“These tests demonstrate raw crunching speed of returning row data, if you are using complex queries where you have slow result times (greater than 10ms) from the database, all of these timings for the connection layer become negligible.
One solution does not fit all, as with most programming practices. Use your best judgment and try to keep your code simple, but not so simple that it creates an efficiency bottleneck. Real world is somewhere between the 1000 query result and the 1 query result set. Use your discursion on where your code resides within these bounds. These results lend me to emphasize that you use object oriented best practices around all your code, but if necessary on pure raw atomic crunching queries, use your judgment on when to jump the fence to the raw crunching power of ADO.NET or JDBC. Make sure your code is well commented.
JavaHibernateSQL/NHibernateToSQL(.NET) and compiled Linq queries appears to perform approximately 2 times slower than raw JDBC/ADO.NET at worst. Overhead as expected with an ORM”

But, after looking at his code I was disappointed that many benchmark considerations like cache, DB size … as explain above didn’t take into consideration here.

My favorite (which still need a lot of improvements):

This benchmark was published by PolePostion. PolePosition is a benchmark test suite to compare database engines and object-relational mapping technology. As of today it is by no means complete. Database vendors and open source database project participants are invited to improve the test implementations and to contribute further disciplines ("Circuits"). The PolePosition framework source code enable implementing new tests quickly and help measuring time, and outputs the results as number series and graphic visualizations.
They have some test suite for example – Barcelona:
Writes, reads, queries and deletes objects with a 5 level inheritance structure

The read results:
t [time in ms]
selects:100
objects:1000
selects:100
objects:3000
selects:100
objects:10000
selects:100
objects:30000
150
433
1317
4068
574
1300
4255
12377
331
990
3368
10530
19
43
162
483


But, The tests were written by people that admit they are not familiar with Hibernate also a lot of consideration in benchmarks as explain above didn’t take into consideration.
Any way – they did a great work and invested in code. Still they need to do some additional work there in order to be an excellent reference
This benchmark was published on Hibernate forum and gets the usual
Hibernate team answer:
“Since this "benchmark" has been written by someone who admits that he doesn't know anything about Hibernate, you won't get much usable information out of it. This particular thing has been debunked internally by a member of our team in 15 minutes - with now Hibernate being "100x faster". There is just no value in publishing this, since it would a) encourage others to waste our time again with similar stuff and b) cost more of our time than it is worth.

We get many benchmarks like this from competing vendors (note that this is particular benchmark very likely encouraged and/or sponsored by an object database vendor) and we don't have the time to debunk them all. We encourage you to create your own benchmarks if you want objective results. Some trivial micro-benchmarks that show the real JDBC overhead for unrealistic non-concurrent data access are available in the Hibernate distribution, as the "ant perftest" target.”

Overhead – is it the best tool for compare?
Look at the benchmark above, if you build your conclusion on the HSQLDB results you can come to a misleading conclusion that Hibernate overhead is 700% compared to JDBC, because as you can see above that HSQLDB JDBC time measurement is 19 and Hibernate time is 150. The overhead as a single metric is misleading in this case, because when deal with in memory DB or local DB or cached DB or small tables or simple model, any overhead added by the ORM is massively exaggerated compared to production scenarios. So overhead is not always the best tool.

What about Hibernate own tests?

Hibernate have a minimal and simple performance test, located under Hibernate source:
Hibernate-distribution-3.5.1-Final\project\testsuite\src\test\perf\org\Hibernate\test\perf\NewerPerformanceTest.java.
The model is simple and the DB doesn’t contain a lot of records, so the tests suffer from exaggeration of the ORM part. Even so I run them on local MySql and the results was 100% overhead. On a production DB (contention on the DB, complex model, remote…) the overhead will be much smaller, but I didn’t test it. In a post I published on Hibernate forum I encouraged Hibernate team to publish their tests and to have more performance visibility. When examining Hibernate we don’t need to focus on overhead only, we need to examine how much time it add to our specific application use cases. When you evaluate you should take into consideration – first and second level cache, lazy loading, merge algorism, optimistic lock handling and etc which can significantly reduce performance impact. In addition, don’t forget the Pareto rule. For the 20% hard problems that don’t get a full solution by Hibernate you can always fall back to direct JDBC, so when you make your considerations it’s very important to focus on the 80%.

Conclusions:

1.       Fact#1 - Hibernate works. Fact#2 –on average enterprise application it can work with good performance. Those two facts get an approval by thousand applications, which are shipped with Hibernate.
2.       Don’t believe to any benchmark that you see on the internet.
3.       Try to create your own benchmark based on your application needs, based on your application architecture (remote or local db/cache policy…).Run the benchmark on semi production environment.
4.       When you create a benchmark, focus on the 80%. Test the average scenario. The other 20% can get an alternative solution. Don’t chose a solution that cover all the 100% but required a lot of investment and has a curve learn.
5.       Overhead can be misleading. The real factor is the fixed time that adds to the use case.
6.       Hibernate is not suited to all applications. There are lots of alternatives out there like IBatis, Spring JDBC…
7.       Creating a good benchmark is not easy. Many factors are involved
8.       It will be great if hibernate team will improve their performance visibility. Cooperation with “PolePostion” is required.

Thanks to Yair Fine for the English review,I invented a new language when i wrote it and thank to Yair help the post now can read by brave English reader and not limited only to "Avihai" speakers, however all syntax mistake belong to me and Yair didnt have time to cover all.



Hibernate - Don't forget the first level cache

A lot of developers ignore or forget about hibernate first level cache.
Hibernate firs level cache is part of the session and not visible to other sessions.
The first level cache cannot be disable and its not optional like the second level cache.
In the first level cache hibernate use in order to store  attached entities. This is in order to:
1. Performance - avoid db hit for re fetch of the same entity more than one time during the transaction.

2. Avoid "shadow object" in order to track on attache entities changes. Explain:
 Well imagine this code:
c1 = session.get(Customer.class, 42);
c2 = session.get(Customer.class, 42);
(note: the get could be replaced with any other kind of query, hql, criteria, *lazy navigation* etc.)

If hibernate doesn't store the attached entities in the first level cache than we will have two different instance of the same customer row. So,
assertSame(c1, c2); should fail but
assertEqual(c1, c2); would actually pass (if you have a proper equal/hashcode implementation)

What wrong with this?
Changing c1 attributes would not affect c2, so hibernate doesn't allow to have more than one instance of the same entity attached to the session.Hibernate do this by using a central place to control on all attached entities. this placed is called- first level cache. Any get  (actually not any . We can bypass it like using statelesession for example ) and update on entity
If Hibernate (or any other JPA implementation) would not do this you would have these “shadow objects” all over the place and the developer will need to manually keep track and ensure that you only use *one* of these objects.


So, this is a build in hibernate mechanism that cannot be turn off- why should i care about it?
Good question (this is the reason i wrote it :) ).
Answer:
A lot of developers complaints on hibernate come-up from not understanding  hibernate mechanism.
In the continue i will a link to 2 posts that talk about problems in hibernate . which can be solved by right use in the hibernate framework.

The main reason that you should be aware to the first level cache is - performance.
Attach entity has a cost:
Cost of using proxy, cost of tracking (hibernate need to keep track on the object state), keep of synchronize  - in flush hibernate need to check if it should synchronize the object to the db. the check and the write to the db cost a lot and in most cases they are not necessary, memory - the object leave in the memory even if we are not going to use it any more.

In the following post avoiding-caching-to-improve-hibernate-performance the developer describe a common use case scenario. he has a XML which each element in the XML is a combination of few hibernate entities. he read element from the XML , do some db query for load references entities, look up data, validations and etc create entities based on the XML element and save it to the db. Since he want to get a good performance by avoid loading data from the db for each XML element, he didn't open hibernate session for each XML element.
He was sure that in this way he can utilize the hibernate first level cache and avoid hit the db for each element.
But, he observed that the performance decrease and the processing time required per input record in the data set increased linearly.

The reason - first level cache. The first level cache is get bigger and bigger during the processing time and this has major impact on hibernate performance. Most of the time is spent around hibernate synchronization mechanism (flush).

So - what is the lesson?
You should always concern about your first level cache. If you need the objects only once in the session load them in minimal scope by stateless session by this hibernate will not need to produce proxies, keep track on the objects and they will be free to be collected by the GC.
Another options:
use in readonly mode for read only entities (there are additional options to define read-only).
Define entities as immutable were optional.
Clear the first level cache from unnecessary entities.

How to clear the first level cache?
JPA API doesn't support in clear specific instances. It support only in clear all .Hibernate API allow you to clear specific instances . If you did changes to the instances make sure that you call to flush before clear . The entities become detached after clear , which mean hibernate will not keep track on them and  their state will not be synchronized with the db.

Solving by design - another design approach like use in process-context for the read-only data and session for each element processing can also solve the problem and in this way have short live session, short db transactions, avoid trigger flush during the process.

further reading  :

Hibernate - should i fetch and how?

In  the top application bottlenecks we find issues regarding to the database area. When dealing with DB we need to plan well - the access and the fetching scope.

Since DB is the bottleneck hibernate, as a third party that work against the database, has a major impact on the application performance.
Lot of people look for a mystery configuration flag that will boost their "hibernate performance". I am sorry to disappoint you there isn't such flag. I search on all hibernate source code for an attribute name - "boost performance" and didn't find it. There are some hibernate configuration that can affect the application performance like batch size and etc , but don't hang up your hopes on those configurations.
If there is performance problem- they mostly hide in your application and not in hibernate global configuration.

In most cases either you load too much information or your current fetch plan is not the best choice.
Hibernate have some attributes which control on the data fetching.

The main two are:
1. Lazy - true/false
2. Fetch strategy - select,subselect,batch,join

The lazy - control on -"when" should I fetch the association now!!!! Immediately, with the association owner.
The fetch strategy control on "how"- should i load them in join with the owning entity? Should I load them in second select...
Obviously the attribute has some overlap. If you chose in fetch strategy join this means that you need to load them with the owning entity (the answer to the "when" is now).
So if the fetching is too slow - check the fetching plan - did you load too much information, did you have many db access? Should I change the plan?
Developers love to thing on magic solution- one solution for all problems. we told a lot of time that join is the best solution since it minimize the db access - so again sorry to disappoint you the answer is not- join is not the best answer for all situations (i will expand on this in the near future).

So now you need some details. as a java programmer I believe in reuse so I will give an excellent references.
http://www.mkyong.com/hibernate/hibernate-fetching-strategies-examples/
http://www.javalobby.org/java/forums/m91885142.html
http://community.jboss.org/wiki/AShortPrimerOnFetchingStrategies

Explore the hibernte world via hibernate source code







עבור מתכנת טובה דוגמה אחת של קוד מממגות של PDF.
היום כאשר יותר ויותר פרויקטים מקפידים על כתיבת UNIT- TEST  ניתן לנצל זאת על מנת ללמוד על אופן השימוש בקוד ולשחק בכל מיני מצבים מבלי צורך להקים סביבה משלכם.

למשל ,אם ברצונכם ללמוד כיצד למפות Interface ב- Hibernate אז עיון ברוב הספרים לא יניב לכם תובנות. ודוגמאות באינטרנט תמיד חסרות משהו.
מה שצריך לעשות זה פשוט לעיין בפרויקט ה- TEST של HIBERNATE ולחפש דוגמא לזה.
ניתן לשחק עם הדוגמא במחשב שלכם, לשנות, לבדוק את הבעיה שלכם, מבלי שיש צורך להקים סביבה.

שלבים:
1. הורידו את ה- SOURCES. שני דרכים:
   DISTRIBUTION BUNDEL - קובץ ZIP שמכיל את ה- SOURCE וגם תוצרים  או משיכה של ה- sources מ -svn.
     
2. קימפול :
בלינק הבא קיימים הוראות קימפול ב- maven. 
http://www.hibernate.org/sourcecode.html

שימו לב להערה לגבי doc-plugin שנמצאת בסוף המסמך.תכשלו אם לא מותקן לכם במחשב KDE זה לא יעבוד ולכן דלגו על שלב בניית ה - doc . בסוף הלינק יש הסבר איך.


המקום שכדאי לחפש בו תובנות לגבי איך עובדים הוא פרויקט  - testsuite
הפרויקט מכיל תתי ספריות עם tests לפי אזורי כיסוי.  {distribution-location}\project\testsuite\src\test\java\org\hibernate\test}
בנוסף תמצאו שם גם בדיקת ביצועים תחת  -  {distribution-locationl\project\testsuite\src\test\perf\ 


hibernate  מנצל את יכולת הפילטור של maven (החלפת משתנים בזמן הקימפול- טוב לצורך החלפת כל מיני משתנים שהם תלויי סביבה), ולכן תמצאו בהרבה פרויקט קובץ בשם  - hibernate.properties ובו מוגדרים כל מיני משתני סביבה של hibernate כדוגמת - dialect ... 
גם בפרויקט הזה יש משתנים כאלה. אתם יכולים למלא אותם בערכים משלכם או לחלופין להריץ בפרופיל hsqldb , פרופיל שמוגדר ב- pom הראשי ובו מוגדרים ערכים עבור המשתנים האלה.