Showing posts with label Hibernate. Show all posts

Constraints validation for user inputs (javax.validation.constraints)

User input validation is common part of any application. JBoss developers made it easy to validate inputs using Java Bean Validation framework.

Bean Validation 2.0 (http://beanvalidation.orgJSR 380)
We will be using Bean Validation framework 2.0 for the example. Its certified implementation is Hibernate Validator 6.0.1.Final or above. Framework 2.0 require Java 8 or higher version.

Source code (User.java)
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;

/**
 * @author javaQuery
 * @since 2018-02-24
 * @github: https://github.com/javaquery/Examples
 */
public class User {

    @NotEmpty(message = "firstName can not be empty")
    @Size(min = 2, max = 20, message = "firstName length must be between 2 and 20")
    private String firstName;

    @NotEmpty(message = "lastName can not be empty")
    @Size(min = 2, max = 20, message = "lastName length must be between 2 and 20")
    private String lastName;

    @NotEmpty(message = "nickNames can not be empty")
    private List<@Size(min = 2, message = "nickName length must be greater than 2") String> nickNames;

    @Email
    private String email;

    @NotEmpty(message = "password can not be empty")
    @Size(min = 6, message = "password length must be at least 6 character")
    private String password;

    // getter-setter
}
  • @NotEmpty - We are using it to check string can not be empty. Can be used with collection, map or array.
  • @Size - We are using it to check the length of string. Can be used with collection, map or array.
  • @Email - The string has to be a well-formed email address.
There are other annotations like @NotNull, @Min, @Max@Past, @Future, @PastOrPresent, @FutureOrPresent, etc... Complete list of annotations is available on Bean Validation specification.

Source code (ValidatorFactoryExample.java)
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

/**
 * @author javaQuery
 * @since 2018-02-24
 * @github: https://github.com/javaquery/Examples
 */
public class ValidatorFactoryExample {

    public static void main(String[] args) {
        User user = new User();
        user.setFirstName("Vicky");
        user.setEmail("not-an-email");
        user.setNickNames(Arrays.asList("vicks", "v"));
        user.setPassword("1234567");
        
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        /* validate object and get constraints failed */
        Set<ConstraintViolation<User>> violations = validator.validate(user);
        
        for (ConstraintViolation<User> violation : violations) {
            System.err.println(violation.getMessage());
        }
    }
}

Output
nick name lenght must be greater than 2
lastName can not be empty
must be a well-formed email address

Other frameworks like Spring triggers validation using annotation so you don't have to validate bean on your own like we did using ValidatorFactory.

Similar
Passing and validating RequestParam in spring-boot rest api

What is the difference between HQL and Criteria in Hibernate?

HQL (Hibernate Query Language)

  • HQL can be used to perform SELECT, INSERT, UPDATE, DELETE.
  • SQL injection possible if not used parameterized query.
  • SELECT STATEMENT: You've to manually write the long queries, take care of where and other syntax.

Criteria

  • Criteria can be used to perform only SELECT.
  • SQL injection is not possible with Criteria because hibernate will take care of it while generating SQL query.
  • SELECT STATEMENT: Criteria interface comes with handy methods and take care of where and other syntax.

These are the basic difference between HQL (Hibernate Query Language) and Criteria. Do comment if other important difference is there.

Check out the stackoverflow thread for performance of Hibernate Criteria vs HQL: which is faster?

Hibernate one to many mapping example [Annotation]

We are going to understand hibernate one-to-many relationship on following table structure...

country table holds one-to-many relationship with state table. Where relationship id resides in state table.

Hibernate One to Many mapping

Before we see the complete code, lets first understand how to define relationship in code.

Country.java, State.java

one to many hibernate

Source code (Country.java)
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * @author javaQuery
 * @date 11th April, 2017
 * @Github: https://github.com/javaquery/Examples
 */
@Entity
@Table(name = "country")
public class Country implements Serializable {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;

    @Column(name = "name")
    private String name;

    @OneToMany(mappedBy = "country" /*, fetch = FetchType.LAZY*/)
    private Set<State> states = new HashSet<State>();
    
    //getter-setter
}

Source code (State.java)
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

/**
 * @author javaQuery
 * @date 15th June, 2017
 * @Github: https://github.com/javaquery/Examples
 */
@Entity
@Table(name = "state")
public class State implements Serializable{

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "country_id")
    private Country country;

    @Column(name = "name")
    private String name;
    
    //getter-setter
}

Source code (OneToManyMappingExample.java)
import com.javaquery.bean.Country;
import com.javaquery.bean.State;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Hibernate one to many example.
 * 
 * @author javaQuery
 * @date 15th June, 2017
 * @Github: https://github.com/javaquery/Examples
 */
public class OneToManyMappingExample {

    public static void main(String[] args) {
        try {
            /* Create hibernate configuration. */
            Configuration configuration = new Configuration();
            configuration.configure("com\\javaquery\\database\\hibernate\\hibernate.cfg.xml");

            /* Open session and begin database transaction for database operation. */
            SessionFactory sessionFactory = configuration.buildSessionFactory();
            Session session = sessionFactory.openSession();

            Country country = session.load(Country.class, 1L);
            if(!country.getStates().isEmpty()){
                for (State state: country.getStates()) {
                    System.out.println(state.getName());
                }
            }else{
                System.out.println("No states found!");
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Output
Hibernate: 
    select
        country0_.id as id1_1_0_,
        country0_.name as name2_1_0_ 
    from
        country country0_ 
    where
        country0_.id=?
Hibernate: 
    select
        states0_.country_id as country_3_3_0_,
        states0_.id as id1_3_0_,
        states0_.name as name2_3_1_ 
    from
        state states0_ 
    where
        states0_.country_id=?
  
Banglore
Gujarat
Mumbai

Hibernate one to one mapping example [Annotation]

We all understand one-to-one relation in database but when it comes to Hibernate I always stuck at which annotation to use and where should I place it?

We are going to understand the hibernate one-to-one relationship on following table structure.
- country table holds the one-to-one relationship with languages table. Where relationship id resides in country table.
- country table holds the one-to-one relationship with capital table. Where relationship id resides in capital table.


Before we see the complete code, lets first understand how to define relationship in code.

Country.java (country - languages)


Capital.java (country - capital)


Source code (Country.java)
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * @author javaQuery
 * @date 11th April, 2017
 * @Github: https://github.com/javaquery/Examples
 */
@Entity
@Table(name = "country")
public class Country implements Serializable {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;

    @Column(name = "name")
    private String name;

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "country")
    private Capital capital;

    @OneToOne
    @JoinColumn(name = "primary_language_id", referencedColumnName = "id")
    private Language language;
 
    //getter-setter
}

Source code (Language.java)
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * @author javaQuery
 * @date 1th April, 2017
 * @Github: https://github.com/javaquery/Examples
 */
@Entity
@Table(name = "languages")
public class Language implements Serializable{
    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;
    
    @Column(name = "language")
    private String language;
 
    //getter-setter
}

Source code (Capital.java)
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * @author javaQuery
 * @date 11th April, 2017
 * @Github: https://github.com/javaquery/Examples
 */
@Entity
@Table(name = "capital")
public class Capital implements Serializable{
    
    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;
    
    @Column(name = "name")
    private String name;

    
    @OneToOne
    @JoinColumn(referencedColumnName = "id", name = "country_id")
    private Country country;
 
    //getter-setter
}

Source code (OneToOneMappingExample.java)
import com.javaquery.bean.Country;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * @author javaQuery
 * @date 11th April, 2017
 * @Github: https://github.com/javaquery/Examples
 */
public class OneToOneMappingExample {

    public static void main(String[] args) {
        try {
            /* Create hibernate configuration. */
            Configuration configuration = new Configuration();
            configuration.configure("com\\javaquery\\database\\hibernate\\hibernate.cfg.xml");

            /* Open session and begin database transaction for database operation. */
            SessionFactory sessionFactory = configuration.buildSessionFactory();
            Session session = sessionFactory.openSession();
            
            Country country = session.load(Country.class, 1L);
            System.out.println(country);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Output
Hibernate: 
    select
        country0_.id as id1_1_0_,
        country0_.primary_language_id as primary_3_1_0_,
        country0_.name as name2_1_0_,
        language1_.id as id1_2_1_,
        language1_.language as language2_2_1_,
        capital2_.id as id1_0_2_,
        capital2_.country_id as country_3_0_2_,
        capital2_.name as name2_0_2_ 
    from
        country country0_ 
    left outer join
        languages language1_ 
            on country0_.primary_language_id=language1_.id 
    left outer join
        capital capital2_ 
            on country0_.id=capital2_.country_id 
    where
        country0_.id=?

Country{id=1, name=India, capital=Capital{id=2, name=Delhi}, language=Language{id=2, language=Hindi}}

What is SQL Injection and how to avoid it in Java?

SQL Injection
Its a technique where attacker try to alter(modify/change) your SQL query using input parameters.
SQL injection may leads to unexpected transaction (i.e select, update, delete, etc...). We'll see the basic SQL injection examples and later on see how to prevent it using Prepared Statement, Hibernate Criteria and HQL.

Source code (SQLInjection.java)
import java.util.ArrayList;
import java.util.List;

/**
 * Example of SQL injection.
 * @author javaQuery
 * @date 8th November, 2016
 * @Github: https://github.com/javaquery/Examples
 */
public class SQLInjection {

    public static void main(String[] args) {
        /* You are getting parameter value from web page or other user input */
        String parameter = "12"; // normal condition
        new SQLInjection().getUser(parameter);

        /**
         * SQL injection using parameter value. 
         * - If user can change parameter in url, use some script, etc...
         */
        parameter = "12 or 1 = 1";
        new SQLInjection().getUser(parameter);
    }

    /**
     * Get user from database.
     * @param id
     * @return 
     */
    public List<Object> getUser(String id) {
        List<Object> result = new ArrayList<Object>();

        String sql = "SELECT * FROM users WHERE id = " + id + ";";
        System.out.println("SQL Query: " + sql);

        /* prepare connection and execute query */
        return result;
    }
}
Output
In following queries, 1st query is valid and return result as expected but when 2nd query is executed it'll select all users from database and that may leads to unexpected behavior of your system.
SQL Query: SELECT * FROM users WHERE id = 12;
SQL Query: SELECT * FROM users WHERE id = 12 or 1 = 1;
In this example I used user table and this table contains very few records 1k, 10k, etc... but
What if you are selecting data from table which contains millions of records? - Answer is SYSTEM CRASH

Other ways of SQL injection
Consider you are getting value of username and password from parameter into param_username and param_password.
String param_username = "\" or \"\"=\"";
String param_password = "\" or \"\"=\"";

//SQL Injection:
String sql = "SELECT * FROM users WHERE username = \"" + param_username + "\" AND password = \"" + param_password +"\"";
System.out.println(sql);
//OUTPUT: SELECT * FROM users WHERE username = "" or ""="" AND password = "" or ""=""

============================================
String param_userid = "123; DROP TABLE messages;";

//SQL Injection:
String sql = "SELECT * FROM users WHERE id = " + param_userid;
System.out.println(sql);
//OUTPUT: SELECT * FROM users WHERE id = 123; DROP TABLE messages;

First and foremost way: Handle Datatypes
For the sake of simplicity developers don't handle data types at coding. In above code I used String as input parameter in method getUser but should've use Integer/Long. If I used Integer or Long then I've to convert String => 12 or 1 = 1 to Integer/Long => Not Valid Number. It'll prevent SQL Injection.


Avoid SQL Injection using Prepared Statement
Prepared Statement doesn't append values in your SQL query rather it provide SQL query and parameter values separately to database. Database will take care of every parameter value for escape character, special character and every other precaution needed.

Source code (PreparedStatementExample.java)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Example of SQL injection.
 * @author javaQuery
 * @date 8th November, 2016
 * @Github: https://github.com/javaquery/Examples
 */
public class PreparedStatementExample {
    public static void main(String[] args) {
        new PreparedStatementExample().getUser("12");
    }
    
    /**
     * Get user from database.
     * @param id
     * @return 
     */
    public List<Object> getUser(String id) {
        List<Object> result = new ArrayList<Object>();

        String sql = "SELECT * FROM users where id = ?;";

        /* prepare connection and execute query */
        try {
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo", "root", "root");
            PreparedStatement prepareStatement = connection.prepareStatement(sql);
            prepareStatement.setInt(1,Integer.parseInt(id)); // index of ? is '1', perform null/number check for 'id'
            //execute prepared statement
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        
        return result;
    } 
}
Output
With PreparedStatement only following query can be generated.
SELECT * FROM users where id = 12;
prepareStatement.setInt: 12 or 1 = 1 is passed as value then Integer.parseInt will throw java.lang.NumberFormatException: For input string: "12 or 1=1".
prepareStatement.setString: What happen if String is used for Number data type in MySQL?


Avoid SQL Injection using Hibernate Criteria
Hibernate Criteria internally uses Prepared Statement to execute query.

Source code
String param_id = "12";

Criteria criteria = session.createCriteria(User.class);
/**
 * 'param_id' provided as String but 'id' declared as Integer/Long in User.java
 * So it'll throw exception(java.lang.String cannot be cast to java.lang.Integer) for invalid data type. (SQL injection handled)
 */
criteria.add(Restrictions.eq("id", param_id));
User user = criteria.uniqueResult();

==============================

// valid query
Integer param_id = 12;

Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.eq("id", param_id));
User user = criteria.uniqueResult();

Avoid SQL Injection using HQL
Its same as Hibernate Criteria.

Source code
String param_id = "12";

Query query = session.createQuery("FROM User WHERE id = :param_id");
/**
 * 'param_id' provided as String but 'id' declared as Integer/Long in User.java
 * So it'll throw exception(java.lang.String cannot be cast to java.lang.Integer) for invalid data type. (SQL injection handled)
 */
query.setParameter("param_id", param_id);
query.list();

==============================

// valid query
Integer param_id = 12;

Query query = session.createQuery("FROM User WHERE id = :param_id");
query.setParameter("param_id", param_id);
query.list();

How to get valued query from Hibernate Criteria(Not Logger)?


As per my knowledge there is no library available that allows you get Criteria query with its real values. So I came up with solution that allows you to do that.

Hibernate Assist, Its an open source Hibernate Criteria analysis tool. It has many features one of them is to get Criteria query with its value.

Download Librarywww.javaquery.com/p/hibernateassist.html

Source Code
Criteria criteria = objSession.createCriteria(User.class);
criteria.createAlias("Messages", "Messages");
criteria.createAlias("CreditCard", "CreditCard");
criteria.add(Restrictions.eq("Email", "vicky.thakor@javaquery.com"));
List<User> listUser = criteria.list();

HibernateAssist objHibernateAssist = new HibernateAssist(objSession);
objHibernateAssist.setCriteria(criteria);
String strQuery = objHibernateAssist.getValuedCriteriaQuery();
System.out.println(strQuery);

Output
SELECT this_.id                        AS id0_2_, 
       this_.username                  AS username0_2_, 
       this_.password                  AS password0_2_, 
       this_.email                     AS email0_2_, 
       messages1_.id                   AS id1_0_, 
       messages1_.user_id              AS user2_1_0_, 
       messages1_.message_text         AS message3_1_0_, 
       creditcard2_.id                 AS id2_1_, 
       creditcard2_.user_id            AS user2_2_1_, 
       creditcard2_.credit_card_number AS credit3_2_1_ 
FROM   user_master this_ 
       INNER JOIN message messages1_ 
               ON this_.id = messages1_.user_id 
       INNER JOIN creditcard creditcard2_ 
               ON this_.id = creditcard2_.user_id 
WHERE  this_.email = 'vicky.thakor@javaquery.com' 
Note: I tried to manage almost all cases however if you find for your Criteria its not working please comment your issues.

Hibernate Disjunction with Example

Hibernate Disjunction with Example

Hibernate Disjunction, is used to add multiple condition in SQL query separated by OR clause within brackets. To generate following query using Hibernate Criteria we need to use Disjunction.

Query
select
 this_.id as id0_0_,
 this_.username as username0_0_,
 this_.email as email0_0_ 
from
 user_master this_ 
where
(
 this_.username=? 
 or this_.username=?
)

Source Code
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Restrictions;

/**
 * Hibernate Conjunction with Example
 * @author javaQuery
 */
public class HibernateDisjunctionExample {

    public static void main(String[] args) {
        /* Create hibernate configuration. */
        Configuration objConfiguration = new Configuration();
        objConfiguration.configure("com\\hibernateassist\\hbm\\hibernate.cfg.xml");

        /* Open session and begin database transaction for database operation. */
        SessionFactory objSessionFactory = objConfiguration.buildSessionFactory();
        Session session = objSessionFactory.openSession();
        
        /* Create criteria */
        Criteria criteria = session.createCriteria(User.class);
        
        /* Create object of Disjunction */
        Disjunction objDisjunction = Restrictions.disjunction();
        /* Add multiple condition separated by OR clause within brackets. */
        objDisjunction.add(Restrictions.eq("Username", "vicky"));
        objDisjunction.add(Restrictions.eq("Username", "thakor"));
        
        /* Attach Disjunction in Criteria */
        criteria.add(objDisjunction);
        
        /* Execute criteria */
        criteria.list();
    }
}

Hibernate Conjunction with Example

Hibernate Conjunction

Hibernate Conjunction, is used to add multiple condition in SQL query separated by AND clause  within brackets. To generate following query using Hibernate Criteria we need to use Conjunction.

Query
select
 this_.id as id0_0_,
 this_.username as username0_0_,
 this_.email as email0_0_ 
from
 user_master this_ 
where
(  
 this_.username=? 
 and this_.username=? 
)

Source Code
Following code will generate above given query.
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.Restrictions;

/**
 * Hibernate Conjunction with Example
 * @author javaQuery
 */
public class HibernateConjunctionExample {

    public static void main(String[] args) {
        /* Create hibernate configuration. */
        Configuration objConfiguration = new Configuration();
        objConfiguration.configure("hibernate.cfg.xml");

        /* Open session and begin database transaction for database operation. */
        SessionFactory objSessionFactory = objConfiguration.buildSessionFactory();
        Session session = objSessionFactory.openSession();
        
        /* Create criteria */
        Criteria criteria = session.createCriteria(User.class);
        
        /* Create object of Conjunction */
        Conjunction objConjunction = Restrictions.conjunction();
        /* Add multiple condition separated by AND clause within brackets. */
        objConjunction.add(Restrictions.eq("Username", "vicky"));
        objConjunction.add(Restrictions.eq("Username", "thakor"));
        
        /* Attach Conjunction in Criteria */
        criteria.add(objConjunction);
        
        /* Execute criteria */
        criteria.list();
    }
}

How Hibernate interpret Order of JOIN on a Table?

Hibernate Logo


Hibernate is one of the greatest framework to interact with database but every framework has its own advantages and disadvantages. Haphazard use of Hibernate may slower your application and you'll face major performance issues.

"Hibernate ain't important than database, you should care How Hibernate execute queries against database"

I've prepared sample mapping file to join two table "vehicle_master" and "profile_master" (It may not make sense but this is just an example so just ignore it).
/* user.hbm.xml */
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="javaQuery.hibernate.User" table="user_master">
    <id name="id" type="int">
      <column name="id"/>
      <generator class="assigned"/>
    </id>
    <property name="Username" type="java.lang.String">
      <column name="user_name"/>
    </property>
    <property name="Email" type="java.lang.String">
      <column name="email"/>
    </property>
    <list cascade="refresh" name="listVehicle" table="user_vehicle_map">
      <key column="user_id"/>
      <index column="idx" type="integer"/>
      <many-to-many class="javaQuery.hibernate.Vehicle" column="vehicle_id"/>
    </list>
    <many-to-one name="Profile" class="javaQuery.hibernate.Profile" column="profile_id" unique="true" not-null="true" />
  </class>
</hibernate-mapping>

Execute following criteria to get SQL query and lets see "In which order Hibernate interpret your join".
/* Simple Criteria to load user with its vehicles and profile */
Criteria criteria = session.createCriteria(User.class);
criteria.setFetchMode("listVehicle", FetchMode.JOIN);
criteria.setFetchMode("Profile", FetchMode.JOIN);
criteria.list();

Above criteria will generate following SQL as we know it.
SELECT *
FROM   user_master this_
LEFT OUTER JOIN user_vehicle_map listvehicl2_
            ON this_.id = listvehicl2_.user_id
LEFT OUTER JOIN vehicle_master vehicle3_
            ON listvehicl2_.vehicle_id = vehicle3_.id
INNER JOIN profile_master profile4_
       ON this_.profile_id = profile4_.id

Myth
Developer thinks that JOIN on vehicle table took first place in SQL query because we have vehicle table at the first position in Criteria but have you ever tried changing position in Criteria? Lets see what happen if we change position in Criteria. After executing following code you'll get the same SQL query generated by first code.
/* Position of JOIN changed in criteria */
Criteria criteria = session.createCriteria(User.class);
criteria.setFetchMode("Profile", FetchMode.JOIN);
criteria.setFetchMode("listVehicle", FetchMode.JOIN);        
criteria.list();

Why didn't Hibernate change order of JOIN?
Well so far you are living with wrong assumption about How order of JOIN take place in hibernate. Its not the Criteria used by Hibernate to interpret order of JOIN on table. Its the Hibernate Mapping (hbm.xml) file. So if you want to change order of JOIN on table, you'll have to change order in your Hibernate Mapping (hbm.xml) file.

Order changed in Hibernate Mapping file. Compare first and second user.hbm.xml file for Vehicle and Profile.
/* user.hbm.xml */
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="javaQuery.hibernate.User" table="user_master">
    <id name="id" type="int">
      <column name="id"/>
      <generator class="assigned"/>
    </id>
    <property name="Username" type="java.lang.String">
      <column name="user_name"/>
    </property>
    <property name="Email" type="java.lang.String">
      <column name="email"/>
    </property>
    <many-to-one name="Profile" class="javaQuery.hibernate.Profile" column="profile_id" unique="true" not-null="true" />
    <list cascade="refresh" name="listVehicle" table="user_vehicle_map">
      <key column="user_id"/>
      <index column="idx" type="integer"/>
      <many-to-many class="javaQuery.hibernate.Vehicle" column="vehicle_id"/>
    </list>
  </class>
</hibernate-mapping>

Now this hibernate mapping file will generate following SQL query not matter what order you've in your Criteria.
SELECT *
FROM   user_master this_
INNER JOIN profile_master profile2_
       ON this_.profile_id = profile2_.id
LEFT OUTER JOIN user_vehicle_map listvehicl3_
            ON this_.id = listvehicl3_.user_id
LEFT OUTER JOIN vehicle_master vehicle4_
            ON listvehicl3_.vehicle_id = vehicle4_.id 

Why ORDER of JOIN is so important?
You'll get same result in both the queries. However JOIN on table in wrong order may cause performance issue at Database. After all Database have to filter your data based on your joins. This is sample query and will not create major impact because of order of JOIN but in real time application we have lots of joins on table and at that time ORDDER of JOIN does matter. Contact your Database Administrator to understand this performance issue for JOINs.

When Hibernate uses INNER JOIN?

Hibernate Logo

After years of experience working around Hibernate there are very few people actually knows "When Hibernate Uses INNER JOIN". I'm one of 'em till today. Today I drilled further and found 3 cases where Hibernate uses INNER JOIN.

1. not-null attribute
When you specify attribute not-null = "true" in hbm.xml for particular column which used for table joining, It will use INNER JOIN no matter you specified FetchMode.JOIN in criteria.
/* Having not-null = "true" in hbm file, It'll override following FetchMode.JOIN */
criteria.setFetchMode("user", FetchMode.JOIN);

2. createAlias
When you create an alias of table, Hibernate will automatically uses INNER JOIN. Its default setting of hibernate.
criteria.createAlias("user", "user");

3. CriteriaSpecification.INNER_JOIN
Well you can ignore CriteriaSpecification.INNER_JOIN, as it can be used with createAlias. And when you use createAlias hibernate will automatically use INNER JOIN but this is just for the sake of your knowledge.
criteria.createAlias("user", "user", CriteriaSpecification.INNER_JOIN);

Note: If I'm missing any other way let's all know about it. Use comment box below.