martes, enero 31, 2012

One of the common problems of people that start using Hibernate is performance, if you don't have much experience in Hibernate you will find how quickly your application becomes slow. If you enable sql traces, you would see how many queries are sent to database that can be avoided with little Hibernate knowledge. In current post I am going to explain how to use Hibernate Query Cache to avoid amount of traffic between your application and database.

Hibernate offers two caching levels:

The first level cache is the session cache. Objects are cached within the current session and they are only alive until the session is closed.

The second level cache exists as long as the session factory is alive. Keep in mind that in case of Hibernate, second level cache is not a tree of objects; object instances are not cached, instead it stores attribute values.

After this brief introduction (so brief I know) about Hibernate cache, let's see what is Query Cache and how is interrelated with second level cache.

Query Cache is responsible for caching the combination of query and values provided as parameters as key, and list of identifiers of objects returned by query execution as values. Note that using Query Cache requires a second level cache too because when query result is get from cache (that is a list of identifiers), Hibernate will load objects using cached identifiers from second level.

To sum up, and as a conceptual schema, given next query: "from Country where population > :number", after first execution, Hibernate caches would contain next fictional values (note that number parameter is set to 1000):

So before start using Query Cache, we need to configure cache of second level.
First of all you must decide what cache provider you are going to use. For this example Ehcache is chosen, but refer to Hibernate documentation for complete list of all supported providers.

See that in this case cache concurrency strategy is NONSTRICT_READ_WRITE, but depending on cache provider, other strategies can be followed like TRANSACTIONAL, READ_ONLY, ... take a look at cache section of Hibernate documentation to chose the one that fits better with your requirements.

Now second level cache is configured, but not query cache; anyway we are not far from our goal.

Set hibernate.cache.use_query_cache property to true.

And for each cachable query, we must call setCachable method during query creation:

List<Country> list = session.createQuery("from Country where population > 1000").setCacheable(true).list();

To make example more practical I have uploaded a full query cache example with Spring Framework. To see clearly that query cache works I have used one public database hosted in ensembl.org. The Ensembl project produces genome databases for vertebrates and other eukaryotic species, and makes this information freely available online. In this example query to dna table is cached.

First of all Hibernate configuration:

It is a simple Hibernate configuration, using properties previously explained to configure second level cache.Entity class is an entity that represents a sequence of DNA.

To try query cache, we are going to implement one test where same query is executed multiple times.

We can see that we are returning first fifty dna sequences, and if you execute it, you will see that elapsed time between creation of query and commiting transaction is printed. As you can suppose only first iteration takes about 5 seconds to get all data, but the other ones only milliseconds.

The foreach line just before query iteration will print object identifier through console. If you look carefully none of these identifiers will be repeated during all execution. This fact just goes to show you that Hibernate cache does not save objects but properties values, and the object itself is created each time.

Last note, remember that Hibernate does not cache associations by default.

Now after writing a query, think if it will contain static data and if it will be executed often. If it is the case, query cache is your friend to make Hibernate applications run faster.

The main goal of Thymeleaf is to provide an elegant and well-formed way of creating HTML 5 templates. Its Standard and SpringStandard dialects allow you to create powerful natural templates, that can be correctly displayed by browsers and therefore work also as static prototypes.

When you create an application using this archetype, generated web application will be composed by two html templates in WEB-INF/views, one for showing a form using HTML5 and CSS3 and another one for listing inserted data.

Spring controllers are located in controller package.

Application is internationalized too using LocaleChangeInterceptor with en_US as default locale. Properties are in src/main/resources/locale folder.

And finally server-side validation is provided by using JSR-303 provider.

This week I have reached 100K visits on blog. Simply I would like to say thank you very much to all people that have come and found useful information, my intention is writing posts to make developers life easier.

Especially I would like to thank all dzone folks, theserverside people, springsource bloggers, JavaCodeGeeks, and of course my Twitter followers all of them have helped to reach this number of visits.

Open servlet-context.xml and add root and js folder as static resource.

Then go to webapp/resources and create index.html.

Add all Javascript libraries into page, but most important, add them in the same order as appears here, if not, some Javascript failures would appear in your browser and the application will not work.

Note that some content is created directly using HTML tags rather than using Backbone views. Normally page layout, headers, footers ... are treated as static content and they are directly written into page.

Let's start modeling our data, in this case a character with its attributes (id, name, url, isHuman...).

Models in Backbone has a particularity that make them useful, they are an implementation of Active Record pattern, so when you are creating a model you will have CRUD operations against a Rest-WebService. So for example when you call save method of your model, Backbone converts that model to JSON and sends the result to server as HTTP POST (if model has no id), or HTTP PUT (update). Other available operations are fetch (load) and destroy (delete).

See how in this case we have created a Character model setting urlRoot property. This property is used to build endpoint to ResetServer. As long as the endpoint returns JSON for a single character, properties will be merged into model.

And the same applies to Collections. When you call fetch method of characters var, all characters returned by calling GET .../characters will be stored into.

See how easy is implementing a Rest Client using Backbone. And I suppose you are wondering where are attributes' definition? Don't worry, with Backbone is not necessary to explicitly define at definition time.

Now it is time for Views. As I cited at the begin of post, Backbone has template support. For this example two templates are going to be used, one for filling a new character and another for showing character information.

To define a template you must use <script> tag with text/template type instead of text/javascript and an id. The structure is similar to JSP (embeddedHTML code, <%= %> for printing variables and <% %> for logical structures).

Next step is creating Views.

For this example we are going to create three views, one for each template, and one that will be a composition of both.

Let's start with View responsible of showing information of one character.

At line 3 we are loading template content defined previously with idshow-characters, into showCharactersTemplate object.

Next important line is number 6. There we are defining a function that will be invoked each time we want to render a view (one time per character). See how we are passing a model object (trust me it is not defined yet, but will be there), to template. To fill template variables, template engine requires data in JSON format, and Backbone model has a toJSON method. And finally generated html code is saved into el attribute.

Next View is responsible of showing character form, and deal with submit action.

This View shows events handling in Backbone. See line 9. We are defining that when user clicks on tag element "a" with class submit, element defined in new-character template, createOnEnter function is executed.

createOnEnter method does three things:

gets values from template form.

instantiates CharacterModel class. See that this is the place where model attributes are defined.

calls save method. This method sends object data to defined endpoint at server side. Because this operation is asynchronous, a callback is registered, so when a success is received, character is added into characters list.

And last View is a composite view of two previous views, acts as a controller between adding a new character and showing all inserted characters:

Initialize function does all required initializations so UI could be refreshed asynchronously. In first two lines we are binding add and reset functions of characters collection to a method. For example each time add function is called, addCharacter is invoked.

Next line is used to populate data to Collection. When fetch is called an HTTP GET to defined endpoint is sent, data is retrieved and Collection'sadd method is called for each result.

addCharacter function is responsible of creating one View for each character. There is not much secret, we are creating a CharacterView, and appending the result of calling its render method to html element with character-list id.

And finally render function that is responsible of rendering CharacterFormView.

See that page is only loaded first time we access it, subsequent updates are done by DOM manipulations.

To finish I embedded all html file explained here so you can see a global overview of all pieces used. Also feel free to download all Eclipse project. I wish you find this post useful.