Showing posts with label Hibernate. Show all posts
Showing posts with label Hibernate. Show all posts

Wednesday, April 23, 2014

Configuring c3p0 connection provider in Hibernate

When you run your application with default Hibernate configurations you may have seen following line in your console.
>> Using Hibernate built-in connection pool (not for production use!)


What does this mean?


Following is an extract from Hibernate 3.3 documentation:
Hibernate's own connection pooling algorithm is, however, quite rudimentary. It is intended to help you get started and is not intended for use in a production system, or even for performance testing. You should use a third party pool for best performance and stability. 
(Reference: http://docs.jboss.org/hibernate/orm/3.3/reference/.../...)

The same can be found in different words in other Hibernate documentations too. In 4.1:
Hibernate's internal connection pooling algorithm is rudimentary, and is provided for development and testing purposes. Use a third-party pool for best performance and stability.
(Reference:http://docs.jboss.org/hibernate/orm/4.1/devguide/../../..)

So according to the documentation Hibernate does not recommend using its built-in connection provider. The same documentation recommends the c3p0 connection provider to use.

These are the quick steps to add c3p0 as your connection provider


Adding required jars
When you are using c3p0, you need to add these two jars to your project.
c3p0-x.x.x.x.jar
mchange-commons-java-x.x.x.x.jar

However when you have configured c3p0, Hibernate uses its C3P0ConnectionProvider for connection pooling .
So it additionally needs following jar which contains the above class.
hibernate-c3p0-x.x.x.Final.jar

If you are using Oracle as your database you may need to add following library also.
c3p0-oracle-thin-extras-x.x.x.x.jar
However if you are not using CLOB or BLOB data types, you may not need to add them.

Now we have added all the required libraries.

But how do we tell Hibernate to use c3p0 connection provider instead of its inbuilt connection provider?

Hibernate documentation says:
To use a third-party pool, replace the hibernate.connection.pool_size property with settings specific to your connection pool of choice. This disables Hibernate's internal connection pool.

According to this line Hibernate will automatically disables its  internal connection pool if you properly configured the c3p0 (or any third-party pool).

Adding c3p0 properties to hibernate.cfg.xml
Open hibernate.cfg.xml file and add following lines. You can change values according to your requirements.
<property name="hibernate.c3p0.min_size">10</property>
<property name="hibernate.c3p0.max_size">200</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.validationQuery">SELECT 1</property>

Now start your application and you will now not see the line "Using Hibernate built-in connection pool (not for production use!)" in your console. Instead you will see a line like this.
>> Instantiating explicit connection provider:org.hibernate.service.jdbc.connections.
   internal.C3P0ConnectionProvider

You have successfully configured c3p0 connection provider.

According to Hibernate documentation above four parameters are the most important. However there are more other parameters that you can use.
All of them can be found in c3p0 official website.
http://www.mchange.com/projects/c3p0/#hibernate-specific

Usage of above main parameters are listed below.
hibernate.c3p0.min_size - Minimum number of JDBC connections in the pool. (Hibernate default: 1)
hibernate.c3p0.max_size - Max number of JDBC connections in the pool. (Hibernate default: 100)
hibernate.c3p0.max_statements - The size of c3p0's global PreparedStatement cache. (Hibernate default: 0. no caching)
hibernate.c3p0.timeout - Seconds a Connection can remain pooled but unused before being discarded. (Hibernate default:0 never expires)

Friday, April 5, 2013

Hibernate - How to query an entity with selected columns only

In Hibernate usually when we query an entity from database it contains all the data of that row, it means all the data in the columns are contained in that entity object.
For an example assume that you have a table named as user which contains columns id, name, age and address. When you want to query a user row usually you use a query like this.

select user from User user where user.id = 10

You know the returned User object contains all the data of the row(ie. id, name, age and address)
But what can you do if you need to query id, name and age only.
Yes, one solution is to use the required columns in to the query by separating with commas as below and getting an array of values as the result.
select user.id, user.name, user.age from User user where user.id = 10

But there is another way to do this in Hibernate.
You can use a query like this.
select new User(user.id, user.name, user.age) from User user where user.id = 10

Now you get a User object which contains values of id, name and age only. Yes it is that much easy :)

Important: In order to query like this you need to have the appropriate constructor in your entity. For an example according to this example your User class should have following constructor.
public User(Integer id, String name, Integer age) {
  this.id = id;
  this.name = name;
  this.age = age;
}

Saturday, December 1, 2012

How to use rich:beanValidator together with Hibernate annotations to validate input components

<rich:beanValidator/> component from Richfaces is very useful because it lets us validate input components by using Hibernate annotations. This highly reduces our need of writing validator classes.

This tutorial will show you how to use this component with @NotNull annotation to avoid NULL inputs and to display a custom message.

Create a JSF managed bean or a SEAM component as below.
public class MyBean {
  Integer number;
  
  @NotNull(message = "Please enter a value")
  public Integer getNumber() {
    return number;
  }

  public void setNumber(Integer number) {
    this.number = number;
  }
}

You need to add this import.
import org.hibernate.validator.NotNull;

This is your xhtml page.
<h:form>
  <h:inputText value="#{myBean.number}" id="txtNumber">
    <rich:beanValidator/>
  </h:inputText>
  <rich:message for="txtNumber"/>
  <a4j:commandButton value="Submit"/>
</h:form>

In this page we have a <h:inputText>  component. inside it we have a <rich:beanValidator/> component. What that component does is when the user enters a value and click the button that value is validated according to the hibernate annotations in the bean class. In this example since we have used the @NotNull annotation, the value is checked for null. If the value is null then our message "Please enter a value" is displayed in the <rich:message> component.

Similarly toy can use <rich:beanValidator/> component with other Hibernate validator annotations.

✔  You can find a list of validator annotations here

    If your page contains lot of input components you would have to put <rich:beanValidator/>s inside each of them. But it could be painful. So Richfaces introduces another component for this. It is <rich:graphValidator/> component. Instead of using <rich:beanValidator/>s inside each element, you can get the same result by wrapping all the input elements with only one <rich:graphValidator/> as below.


<h:form>
  
  <rich:graphValidator>
    <h:inputText value="#{myBean.number}" id="num" />
    <rich:message for="num" /><br />

    <rich:calendar value="#{myBean.date}" id="dte" />
    <rich:message for="dte" /><br/>
     </rich:graphValidator>

  <a4j:commandButton value="Save" />
</h:form>

Sunday, November 25, 2012

Hibernate InvalidStateException - How to identify invalid fields

    If you are using Hibernate, you should be familiar with the InvalidStateException which is thrown when you are going to persist data to a table with invalid values. Simply by looking at the stack trace it is impossible to find the table columns or Entity fields for which the validations are failed.
    But actually it is not very difficult to find those fields. First you need to catch the InvalidStateException by using a try-catch block. The InvalidStateException class has a method getInvalidValues() which returns an array of InvalidValue s. In this InvalidValue class there are several methods to find the information you need. So by Iterating through this array you can get the info you need.
try {
  //Persistence logic here...
} catch (InvalidStateException e) {
  for(InvalidValue invalidValue : e.getInvalidValues()) {
    System.out.println(invalidValue.getPropertyName());//Property on which validations
                                                       are failed
    System.out.println(invalidValue.getValue());//invalid value
    System.out.println(invalidValue.getMessage());//message for invalid value
    System.out.println(invalidValue.getBeanClass());//Entity bean which belongs the
                                                    property
  }
}