25 February, 2012

hibernate notes

What is Hibernate? 
Hibernate is a pure Java object-relational mapping (ORM) and persistence framework that allows you to map POJO to relational database tables using (XML)
configuration files.

Why do we need hibernate? 
·         object to Relational mapping tool
·         caching present
·          optimized sql statement
·          databases can be changed easily
Advantage of hibernate? 
1)  it shields developers from messy SQL
2)  Improved productivity because of:
       High-level object-oriented API
       Less Java code to write
       No SQL to write
3) Improved performance by caching
4) Improved maintainability as we have to write a lot less code
5) Improved portability as it automatically generates database-specific SQL for you
Ways of Hibernate configuration?
       1)     Programmatic configuration
       2)     XML configuration (hibernate.cfg.xml)
       3)     hibernate.properties

Core interfaces are of Hibernate framework
  * Configuration
  * SessionFactory
  * Session
  * Transaction
  * Query and Criteria

What is Hibernate Query Language (HQL)? 
Hibernate offers a query language to query, store, update, and retrieve objects from a database. This language, the Hibernate query Language (HQL), is an
 object-oriented extension to SQL.

How do you map Java Objects with Database tables in hibernate?
 <hibernate-mapping>
  <class name="hibernate.example.Emp" table="empTable">
   <id name="empId" type="String" column="empId">
    <generator class="assigned" />
   </id>
   <property name="empName">
    <column name="empName" />
   </property>
  </class>
 </hibernate-mapping>


What’s the difference between load() and get() in hibernate?

Load
Get
go for it if u r sure that the object exists
go for it if u r not sure that the object exists
exception is thrown if the unique id is not found in the database
return null if the unique id is not found in the database.
returns a proxy by default and database won’t be hit until the proxy is     first invoked
hit the database immediately


difference between and merge and update?
Merge
Update
merging without consideration of the state of the session. Persistent object get merged.
if you are sure that the session does not contain an already persistent instance with the same id
in the session. If we go for session.merge(e3) then 1,'a' will be replaced in the session with 1,'c'.
If session has e1(1,'a') and e2(2,'b') and we have e3(1,'c'). if we go for session.update(e3) then exception will be thrown as empid=1 is already there
Happen in session on persistent object.
Happen in session on persistent object.

Define cascade and inverse option in one-many mapping in hibernate? 
cascade - enable operations to child entities.
                all|none|save-update|delete|all-delete-orphan
 inverse -indicates which end of a relationship holds the ownership.
              "true|false"

What is named query in hibernate? 
It lets you separate queries from coding section of the application to the mapping xml file(.hbm files).The query is given unique name for the entire
 application. The application can use the query by using the name of the query. This way the application is able to use the same query multiple times without
 writing the same query multiple times.
 <query name="getProductByCode">
        <![CDATA[from Product p where p.code = :code]]>
    </query>

 Query query = session.getNamedQuery("getProductByCode").setString("code", "101");

What is flushing in hibernate?
Flushing the Session simply gets the data that is currently in the session synchronized with what is in the database.
Until we go for commit, data will not get saved in databse.

Difference between hql and sql in hibernate?

Hql
Sql
object oriented
table oriented
optimized sql query gets generated automatically
u have to write the optimized query
less verbose
more verbose
database independent
db dependent

What is n+1 problem in hibernate:

it is a problem in which hibernate goes to DB n+1 times to fetch the data which in normal database operation can be done in 2 round trips.
 Class Emp{
  String empId;
  String empName;
  Set<Account> accounts;
         //getters and setters
 }
 Class Account{
  String accountNo;
  //getters and setters
 }

 Query query = session.createQuery("from Emp");
 List<Emp> empList = query.list();
 System.out.println("----Emp List-----");
 for(Emp emp:empList){
  System.out.println(emp.getEmpId()+"-"+emp.getEmpName());
 }
 System.out.println("--------Account List-----");
 for(Emp emp:empList){
  Set<Account> accounts = emp.getAccounts();
  for(Account account:accounts){
   System.out.println(account.getAccountName()+"-"+account.getAccountNo());
  }
 

 
 output
 ------
Hibernate: select emp0_.emp_Id as emp1_, emp0_.emp_name as emp2_0_ from emp_table emp0_
   Hibernate: select accounts0_.account_emp_id as account3___, accounts0_.account_no as account1___, accounts0_.account_no as account1_0_, accounts0_.account_name as account2_1_0_ from account_table accounts0_ where accounts0_.account_emp_id=1
   Hibernate: select accounts0_.account_emp_id as account3___, accounts0_.account_no as account1___, accounts0_.account_no as account1_0_, accounts0_.account_name as account2_1_0_ from account_table accounts0_ where accounts0_.account_emp_id=2
   Hibernate: select accounts0_.account_emp_id as account3___, accounts0_.account_no as account1___, accounts0_.account_no as account1_0_, accounts0_.account_name as account2_1_0_ from account_table accounts0_ where accounts0_.account_emp_id=3
  
  So, here DB is called each time for every employee to know its accounts to get the total account list. But this thing can be done in db 
  in one shot as : select * from Accounts;

Can we have multiple SessionFactory for a single database in an application?
 Yes. We can have as follows:

 <bean id="abstractSessionFactory" abstract="true"                    
                                    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">                       
<property name="mappingResources">
                <list>
                    <value>product.hbm.xml</value>
                </list>
           </property>
           <property name="hibernateProperties">
               <value>
                  hibernate.dialect=org.hibernate.dialect.HSQLDialect
               </value>
           </property>
  </bean>
  <bean id="mySessionFactory" parent="abstractSessionFactory">
        <property name="dataSource" ref="myDataSource"/>
             ...
  </bean>

  <bean id="mySessionFactory2" parent="abstractSessionFactory">
         <property name="dataSource" ref="myDataSource2"/>
             ...
  </bean>

How to create session in hibernate?
     Configuration config = new Configuration().configure("hibernate/example/hibernate.cfg.xml");
     SessionFactory sessionFactory = config.buildSessionFactory();
     session = sessionFactory.openSession();
     session.close();

What is ORM?
     ORM can be viewed as a bridge between an application and the relational-database that it is 
depending on.
     Mismatch problems:
          Granularity: Sometimes you will have an object model which has more classes than the number of corresponding tables in the database (we says the object model is more granular than the relational model).
          inheritance: object-oriented programming support inheritance but rational tables dont support it
          Identity: A RDBMS defines exactly one notion of 'sameness': the primary key.  Java, however, defines both object identity (a==b) and object equality (a.equals(b)).
          Associations:
          
            Data navigation:
               Object oriented approach: customer.getDept().getName()
               Relational approach: customer and dept tables need to join.

Can we call stored procedure from hibernate and how?
     a) Connection con = session.connection();  // obtain JDBC connection from Session objectCallableStatement cs = con.prepareCall("{ call changesalary(?,?) }");

        b)Using native query
    Query q = session.createSQLQuery(" { call changesalary(?,?) }");


What are types of supported joins? 
 1)inner join:
    Query query = session.createQuery("from Cat cat inner join Owner owner where owner.Name ='Duke'");
 2) outer join
 3)Theta Joins:
       Consider tables Car and Boat which list models of cars and boats and their respective 
prices. Suppose a customer wants to buy a car and a boat, but she does not want to spend more money for the boat than for the car. The theta-join on the relation CarPrice = BoatPrice produces a table with all the possible options.

Car Model
Car Price
 CarA                     
20K
CarB
30K
CarC
50K

Boat Model
Boat Price
 Boat1                    
10K
Boat2
40K
Boat3
60K

CarPrice>=BoatPrice

CarModel
CarPrice
BoatModel
BoatPrice
CarA                                      
20K
Boat1
10K
CarB
30K
Boat1
10K
CarC
50K
Boat1
10K
CarC
50K
Boat2
40K



The result of this operation consists of all combinations of tuples in R and S that satisfy the relation theta.
The result of the theta-join is defined only if the headers of S and R are disjoint, that is, do not contain a common attribute.
4) Fetch join


What is inverse=true?
                The “inverse” keyword is always declare in one-to-many and many-to-many relationship (many-to-one doesn’t has inverse keyword), it means which side is responsible to take care of the relationship.

How to prevent concurrent update in Hibernate
1)  Through version checking.
       Declare a variable "versionId" in your Class with setter and getter.
              Class User{
                     String userName;
                    Long versionId;
              }
2)  in the .hbm.xml file
                <version name="versionId" type="long" column="version" />
3)  Create a coulmn name "version" in the table.




What is lazy fetching in Hibernate?
   Lazy fetching decides whether to load child objects while loading the Parent Object.
   Lazy = true (means not to load child)
   By default the lazy loading of the child objects is true.
   This makes sure that the child objects are not loaded unless they are explicitly invoked in the session by calling getChild() method on parent.In this case hibernate issues a fresh database call to load the child .
But in some cases you do need to load the child objects when parent is loaded.
Just make the lazy=false and hibernate will load the child when parent is loaded from the database.
               
 <hibernate-mapping package="hibernate.example.vo">
      <class name="Emp" table="emp_table" >
           <id name="empId" column="emp_Id">
                 <generator class="sequence" />
           </id>
           <property name="empName" column="emp_name" />
                 <set name="accounts" cascade="all" inverse="false" lazy="true/false">
                       <key column="account_emp_id"></key>
                       <one-to-many class="Account" />
                 </set>
      </class>
</hibernate-mapping>
  If session is closed and we are going for getChild() then lazyInitializationException will be thrown.
 this can be removed by using lazy=false. Even if we don’t want to remove lazy=true then we can go for fetch join from Emp emp join fetch emp.accounts accounts



No comments:

Post a Comment