Hibernate

"Hibernate "


Hibernate, this Sections focuces in Hibernate including Configuration , Hibernate SessionFactory, Hiberante Mapping, HQL, Hibernate Spring Configuration etc.,

1 )   What is Hibernate ?

Ans)
Hibernate is a JAVA based object-relational mapping (ORM) library, providing a framework for
mapping an object-oriented domain model to a traditional relational database. Hibernate
solves object-relational impedance mismatch problems by replacing direct persistence-related
database accesses with high-level object handling functions.
Hibernate's primary feature is mapping from Java classes to database tables (and from Java
data types to SQL data types). Hibernate also provides data query and retrieval facilities.
It also generates the SQL calls and attempts to relieve the developer from manual result
set handling and object conversion and keep the application portable to all supported
SQL databases with little performance overhead.



2 )   Advantages of Hibernate ?

Ans)
i) Hibernate is better then plain JDBC, you can use Hibernate which generates
the SQL on the fly and then automatically executes the necessary SQL statements.
This saves a lot of development and debugging time of the developer. Writing
JDBC statement, setting the parameters, executing query and processing the result
by hand is lot of work. Hibernate will save all tedious efforts.
ii) When you compare with EJB, Hibernate persistence has no requirement for
a J2EE application server or any other special environment. It is, therefore,
a much more suitable solution for stand-alone applications, client-side application
storage, and other environments in which a J2EE server is not immediately available.
iii) Hibernate uses POJOs so these POJOs can be used for different purposes
also like DTOs etc.,
iv) Hibernate does not require you to map one POJO to one table. A POJO can be
constructed out of a selection of table columns, or several POJOs can be persisted
into a single table.

v) Hibernate directly supports inheritance relationships and the various other relationships
between classes.
vi) Any Java object capable of being persisted to a database is a candidate for
Hibernate persistence. Therefore, Hibernate is a natural replacement for ad hoc
solutions, or as the persistence engine for an application that has not
yet had database persistence incorporated into it. Furthermore, by choosing Hibernate
persistence,you are not tying yourself to any particular design decisions for
the business objects in your application.

vii) JPA Provider: Hibernate can work as JPA provider in JPA based applications.



3 )   Hibernate Unit Of Work ?

Ans)
Unit Of work is not thing a Business Transaction in which we could perform
a series of DataBase operations (Transactions) together as a Unit to accomplish the
Business Functionality.
Hibernate stongly recomand not use "session-per-operation antipattern",  meaning do
not open a new Session per each operation in a Business Transaction.
Please use the most common pattern in a multi-user client/server application is
session-per-request. A new Hibernate Session is opened, and all database operations are
executed in this unit of work.



4 )   Hibernate Config in Managed and NonManaged Env

Ans)

  • Hibernate Config in Managed and NonManaged Env
    Sample Img 4
See take a look at above Pic to get an understanding on how Hibernate and its transactions will be
mananaged in both Managed and NonManaged Env.



5 )   How to Load Config File ?

Ans)
SessionFactory sf = new Configuration() .configure("comTest.cfg.xml").buildSessionFactory();



6 )   What is the best possible way to maintain or create the Hibernate Session ?

Ans)
Hibernate stongly recomand not use "session-per-operation antipattern",  meaning do
not open a new Session per each operation in a Business Transaction.
Please use the most common pattern in a multi-user client/server application is
session-per-request. A new Hibernate Session is opened, and all database operations are
executed in this unit of work.
Hibernate provides built-in management of the "current session" to simplify this pattern.
Start a transaction when a server request has to be processed, and end the transaction before
the response is sent to the client. Common solutions are ServletFilter, AOP interceptor with
a pointcut on the service methods, or a proxy/interception container.
Other best way is to get the "HiberanteSession and store in Thread Local" and fetch from Thread
local before open a new Session for any given Request.



7 )   How to get a Hibernate SessionFactory and Session ?

Ans)
public class HibernateUtil {
private static final SessionFactory sessionFactory;
  
  static {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            sessionFactory = new Configuration().configure().buildSessionFactory();

        } catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

}
Get the Session :
 Session session =factory.getCurrentSession();






8 )   Sample Hibernate Config ?

Ans)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
                                         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <!-- a SessionFactory instance listed as /jndi/name -->
  <session-factory name="java:hibernate/SessionFactory">
    <!-- properties -->
    <property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="show_sql">false</property>
    <property name="transaction.factory_class">
      org.hibernate.transaction.JTATransactionFactory </property>
    <property name="jta.UserTransaction">java:comp/UserTransaction</property>
    <!-- mapping files -->
    <mapping resource="org/hibernate/auction/Item.hbm.xml"/>
    <mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
    <!-- cache settings -->
    <class-cache class="org.hibernate.auction.Item" usage="read-write"/>
    <class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
    <collection-cache collection="org.hibernate.auction.Item.bids" usage="read-write"/>
  </session-factory>
</hibernate-configuration>



9 )   Sample programmatic configuration ?

Ans)
SessionFactory sf = new Configuration() .configure("comTest.cfg.xml").buildSessionFactory();



10 )   Transaction strategy configuration ?

Ans)
You have to hibernate know who manages the Trasactions by using
"manager_lookup_class" parameter Based on the Application Server
you deploy your application.
Here are some of the possible values :
org.hibernate.transaction.JBossTransactionManagerLookup                          JBoss AS
org.hibernate.transaction.WeblogicTransactionManagerLookup                     Weblogic
org.hibernate.transaction.WebSphereTransactionManagerLookup                 WebSphere
 org.hibernate.transaction.WebSphereExtendedJTATransactionLookup        WebSphere
Here is Full Configuration :
hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
    org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
    org.hibernate.transaction.JBossTransactionManagerLookup

hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect



11 )   How many ways you could generate IDs in Hibernate ?

Ans)
There are so many ways of generating Ids in Hibernate , but the following are
mostly used
increment
Generates identifiers of type long, short or int that are unique only when no other
process is inserting data into the same table. Do not use in a cluster.
identity
Supports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL.
The returned identifier is of type long, short or int.
sequence
Uses a sequence in DB2, PostgreSQL, Oracle, SAP DB, McKoi or a generator in Interbase.
The returned identifier is of type long, short or int
<id name="id" type="long" column="cat_id">
        <generator class="org.hibernate.id.TableHiLoGenerator">
                <param name="table">uid_table</param>
                <param name="column">next_hi_value_column</param>
        </generator>
</id>

<id name="id" type="long" column="person_id">
<generator class="sequence">
 <param name="sequence">person_id_sequence</param>
</generator>
 </id>



12 )   How you set the System Level Properties in Hiberante ?

Ans)
Some of these properties are "system-level" only. System-level properties
can be set only via
java -Dproperty=value or hibernate.properties
They cannot be set by the other techniques described above.



13 )   How could you get the Raw SQL queries from Hiberante ? Can you also Log all JDBC parameters ?

Ans)
org.hibernate.SQLLog all SQL DML statements as they are executed
org.hibernate.typeLog all JDBC parameters
org.hibernate.tool.hbm2ddlLog all SQL DDL statements as they are executed
The above properties in Hibernate Config should be set as 'true'.



14 )   How to generate Hibernate POJO from config XMLs ?

Ans)
Here the ANT Target.
<target name="hbm2java">
        <taskdef name="hibernatetool"
          classname="org.hibernate.tool.ant.HibernateToolTask" 

          classpathref="lib.classpath"/>
        <hibernatetool destdir="${hbm2java.dest.dir}"
          templatepath="${hbm.template.path}">
          <classpath>
            <path refid="pojo.classpath"/>
          </classpath>        
          <configuration>
            <fileset dir="${hbm2java.src.dir}">
              <include name="**/*.hbm.xml"/>
            </fileset>
          </configuration>
          <hbm2java/>
        </hibernatetool>
    </target> 




15 )   How to get Hibernate different Sessions for Multiple Databases in same applications ?

Ans)
You have to create two separate hibernate Configurations and create
 two different SessionFactories
          // Create the SessionFactory from hibernate.cfg.xml
            sessionFactory = new Configuration().configure(configFile1).buildSessionFactory();
      // Create SessionFactory from second hibernate.cfg.xml
            sessionFactory1 = new Configuration().configure(configFile2).buildSessionFactory();



16 )   Is it required to override equal and Hashcode methods of a Hibernate Objects ?

Ans)
Yes, it is required to override these methods if
  •           it is intended to put instances of persistent classes in a Set
  •           it is intended to use reattachment of detached instances.



17 )   How can you map a table (or view) with no primary key?

Ans)
Every table (or even view) should have some unique key. The mathematical definition of
a relation is a set of tuples. (Sets do not permit duplicate elements.) Furthermore,
truly identical rows can not possibly have any meaningful semantics from the user's
perspective.
In some cases it may be sensible to go as far as mapping all columns of a view as a
<composite-id/>, but there is almost always some smaller business key. (Note that Hibernate
does not require that this unique key be enforced by the database schema, of course.)



18 )   Is the second-level cache enabled by default?

Ans)
No entities or collections will be cached in the second-level cache unless you supply
<cache> elements in the mapping files or <class-cache> and/or <collection-cache> elements
 in hibernate.cfg.xml, even when EHCache or some other cache provider is configured.

Likewise, queries are not cached in the query cache, unless you explicitly call
Query.setCacheable(true), even when the query cache is enabled.



19 )   What is StatelessSession in hibernate ?

Ans)



20 )   Hibernate is leaking JDBC connections ?

Ans)
Following are some possible reasons why Hibernate might not be closing connections:
o You are forgetting to call Session.close().
This is the most common cause. Consider carefully how you are handling sessions.
Are you sure you create only one Session per transaction? Are you certain you close the
Session even if an exception occurs (ie. in a finally block). Hibernate issues a warning
in the log when an unclosed session is garbage collected, so
looking there is a good place to start.
Session s = sf.openSession();
 try {
 // do some work
s.connection().commit();
 } catch (Exception e) {
 s.connection().rollback();
 } finally {
 s.close().close(); //close the session and user-supplied JDBC connection
}
o Hibernate is doing connection pooling.
Which ConnnectionProvider are you using? If its not DatasourceConnectionProvider, then
it is probably doing connection pooling. This can cause problems in certain environments.
Pooling may be disabled for DriverManagerConnectionProvider by setting
hibernate.connection.pool_size=0 in hibernate.properties.



21 )   How to set Lazy for Many-to-One ?

Ans)
<one-to-one constrained="true" fetch="select" lazy="proxy" class="Foo"/>



22 )   What is the importance of "inverse" attribute in Hibernate? How would you inform hibernate which end of relation should be ignored?

Ans)
Essentially "inverse" indicates which end of a relationship should be ignored, so when
persisting a parent who has a collection of children, should you ask the parent for its
list of children, or ask the children who the parents are ?
Here is how you set this parameter in a <many-to-one> relation.
Child :
<hibernate–mapping>
<class name="Child" table="child">
 <many–to–one name="parent"
                 class="Parent"
                 column="parent_id"/>
</class>
</hibernate–mapping>
Parent :
<hibernate–mapping>
<class name="Child" table="child">
<bag name="children" inverse="true" cascade="save–update">
      <key column="parent_id"/>
      <one–to–many class="Child"/>
    </bag>
</class>
</hibernate–mapping>



23 )   Mapping inheritance ? Or How to create a "Subclass" in hibernate ?

Ans)
Hibernate supports the three types of  inheritance:
o Table per Class Strategy: the <union-class> element in Hibernate
o Single Table per Class Hierarchy Strategy: the <subclass> element in Hibernate
o Joined Subclass Strategy: the <joined-subclass> element in Hibernate
The chosen strategy is declared at the class level of the top level entity in the
hierarchy using the @Inheritance annotation.
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Flight implements Serializable { ... }



24 )   Collection mapping in hibernate and How many types of Collection Mappings exist ?

Ans)
The Hibernate mapping element used for mapping a collection depends upon
the type of interface.
Here are list of Collections you can use.
• <set>
• <map>
• <bag>
• <list>
• <array>
Here is a quick sample
<class name="Product">
<id name="serialNumber" column="productSerialNumber"/>
 <set name="parts"> <key column="productSerialNumber" not-null="true"/>
<one-to-many class="Part"/>
</set>
 </class>



25 )   Sample one-to-many / many-to-one relation (Bidirectional ) ?

Ans)
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
 <set name="addresses" table="PersonAddress">
<key column="personId"/>
<many-to-many column="addressId" unique="true" class="Address"/>
</set>

</class>
<class name="Address">
<id name="id" column="addressId">
 <generator class="native"/>
 </id>
 <join table="PersonAddress" inverse="true" optional="true">
  <key column="addressId"/>
  <many-to-one name="person" column="personId" not-null="true"/>
 </join>

 </class>



26 )   Parent Child relation with cascading ?

Ans)
<set name="children" inverse="true" cascade="all">
    <key column="parent_id"/>
    <one-to-many class="Child"/>
</set>
Deleting Parent :
Parent p = (Parent) session.load(Parent.class, pid);
session.delete(p);
session.flush();
Deleting child :
Parent p = (Parent) session.load(Parent.class, pid);
Child c = (Child) p.getChildren().iterator().next();
p.getChildren().remove(c); s
session.delete(c);
session.flush();



27 )   How could you persist the object in Hibernate ?

Ans)
Employee emp = new Employee ();
Emp.setFirstName ("Josh");
sess.save (emp) ;
sess.flush(); //force the SQL INSERT 



28 )   Loading Data in Hibernate ?

Ans)
Employee emp = sess.load(Employee.class, id);



29 )   Querying ?

Ans)
List cats = session.createQuery( "from Employee as emp where emp.firstName = ?") .setString(0, 'Josh') .list();
Query q = sess.createQuery("from Employee as emp where emp.name = :name");
q.setString("name", "Josh");
 Iterator cats = q.iterate();



30 )   What are named queries ?

Ans)
<query name="ByNameAndMaximumWeight"><![CDATA[ from com.Employee as cat where cat.name = ? and cat.weight > ? ] ]></query>
Query q = sess.getNamedQuery("ByNameAndMaximumAge");
Criteria Queries :
Criteria crit = session.createCriteria(Employee.class);
crit.add( Restrictions.eq( "age", '35') );
crit.setMaxResults(10);
List cats = crit.list();



31 )   Queries in native SQL ?

Ans)
List cats = session.createSQLQuery("SELECT {Employee.*}
FROM Employee{Employee} WHERE ROWNUM<10")

.addEntity("Employee", Employee.class) .list();



32 )   Mapping with JPA (Java Persistence Annotations) ?

Ans)
JPA entities are plain POJOs. Actually, they are Hibernate persistent entities.
Their mappings are defined through JDK 5.0 annotations instead of hbm.xml files.
In following Example "status" does not exist in table
@Entity
@Table(name="tbl_sky")
public class Sky implements Serializable {
    private String name;
    private String model;
 @Transient
    private String status;
    @Id
    public String getName() {
        return name;
    }
 }



33 )   Call Stored Procedure from Hibernate

Ans)
Hibernate3 provides support for queries via stored procedures and functions.
Most of the following documentation is equivalent for both.

The stored procedure/function must return a resultset as the first
out-parameter to be able to work with Hibernate.

 An example of such a stored function in Oracle 9 and higher is as follows:
CREATE OR REPLACE FUNCTION selectAllEmployments
    RETURN SYS_REFCURSOR
AS
    st_cursor SYS_REFCURSOR;
BEGIN
    OPEN st_cursor FOR
 SELECT EMPLOYEE, EMPLOYER,
 STARTDATE, ENDDATE,
 REGIONCODE, EID, VALUE, CURRENCY
 FROM EMPLOYMENT;
      RETURN  st_cursor;
 END;
To use this query in Hibernate you need to map it via a named query.
<sql-query name="selectAllEmployees_SP" callable="true">
    <return alias="emp" class="Employment">
        <return-property name="employee" column="EMPLOYEE"/>
        <return-property name="employer" column="EMPLOYER"/>
        <return-property name="startDate" column="STARTDATE"/>
        <return-property name="endDate" column="ENDDATE"/>
        <return-property name="regionCode" column="REGIONCODE"/>
        <return-property name="id" column="EID"/>
        <return-property name="salary">
            <return-column name="VALUE"/>
            <return-column name="CURRENCY"/>
        </return-property>
    </return>
    { ? = call selectAllEmployments() }
</sql-query>


more info...       

34 )   How to use DBCP Connection Pool in Hibernate ?

Ans)
The following steps allows you to use DBCP connection Pool in Hibernate .
Step 1:
Configure you Hibernate Properties as follows .
In Hiberante Properties file or XML file you need to use dbcp Connection API as follows.
hibernate.dialect org.hibernate.dialect.OracleDialect
hibernate.connection.driver_class oracle.jdbc.driver.OracleDriver
hibernate.connection.url jdbc:oracle:thin:@HostName:1522:DBName

hibernate.connection.username sa
hibernate.connection.password yourPassword
hibernate.connection.pool_size 5
hibernate.dbcp.poolPreparedStatements true
#hibernate.dbcp.ps.maxActive
hibernate.connection.provider_class com.salesorder.DBCPConnectionProvider
Step 2 :
Create your own Connection Provider by using DBCP as follows.
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Environment;
import org.hibernate.connection.ConnectionProvider;
import org.hibernate.connection.ConnectionProviderFactory;
public class DBCPConnectionProvider implements ConnectionProvider {
    private static final Log log = LogFactory.getLog(DBCPConnectionProvider.class);
    private static final String PREFIX = "hibernate.dbcp.";
    private BasicDataSource ds;
    // Old Environment property for backward-compatibility (property removed in Hibernate3)
    private static final String DBCP_PS_MAXACTIVE = "hibernate.dbcp.ps.maxActive";
    // Property doesn't exists in Hibernate2
    private static final String AUTOCOMMIT = "hibernate.connection.autocommit";
    public void configure(Properties props) throws HibernateException {
        try {
            log.debug("Configure DBCPConnectionProvider");
         
            // DBCP properties used to create the BasicDataSource
            Properties dbcpProperties = new Properties();
            // DriverClass & url
            String jdbcDriverClass = props.getProperty(Environment.DRIVER);
            String jdbcUrl = props.getProperty(Environment.URL);
            dbcpProperties.put("driverClassName", jdbcDriverClass);
            dbcpProperties.put("url", jdbcUrl);
         
            // Username / password
            String username = props.getProperty(Environment.USER);
            String password = props.getProperty(Environment.PASS);
            dbcpProperties.put("username", username);
            dbcpProperties.put("password", password);
            // Isolation level
            String isolationLevel = props.getProperty(Environment.ISOLATION);
            if ((isolationLevel != null) && (isolationLevel.trim().length() > 0)) {
                dbcpProperties.put("defaultTransactionIsolation", isolationLevel);
            }
         
            // Turn off autocommit (unless autocommit property is set)
            String autocommit = props.getProperty(AUTOCOMMIT);
            if ((autocommit != null) && (autocommit.trim().length() > 0)) {
                dbcpProperties.put("defaultAutoCommit", autocommit);
            } else {
                dbcpProperties.put("defaultAutoCommit", String.valueOf(Boolean.FALSE));
            }
            // Pool size
            String poolSize = props.getProperty(Environment.POOL_SIZE);
            if ((poolSize != null) && (poolSize.trim().length() > 0)
                && (Integer.parseInt(poolSize) > 0))  {
                dbcpProperties.put("maxActive", poolSize);
            }
            // Copy all "driver" properties into "connectionProperties"
            Properties driverProps = ConnectionProviderFactory.getConnectionProperties(props);
            if (driverProps.size() > 0) {
                StringBuffer connectionProperties = new StringBuffer();
                for (Iterator iter = driverProps.keySet().iterator(); iter.hasNext();) {
                    String key = (String) iter.next();
                    String value = driverProps.getProperty(key);
                    connectionProperties.append(key).append('=').append(value);
                    if (iter.hasNext()) {
                        connectionProperties.append(';');
                    }
                }
                dbcpProperties.put("connectionProperties", connectionProperties.toString());
            }
            // Copy all DBCP properties removing the prefix
            for (Iterator iter = props.keySet().iterator() ; iter.hasNext() ;) {
                String key = String.valueOf(iter.next());
                if (key.startsWith(PREFIX)) {
                    String property = key.substring(PREFIX.length());
                    String value = props.getProperty(key);
                    dbcpProperties.put(property, value);
                }
            }
         
            // Backward-compatibility
            if (props.getProperty(DBCP_PS_MAXACTIVE) != null) {
                dbcpProperties.put("poolPreparedStatements", String.valueOf(Boolean.TRUE));
                dbcpProperties.put("maxOpenPreparedStatements", props.getProperty(DBCP_PS_MAXACTIVE));
            }
         
            // Some debug info
            if (log.isDebugEnabled()) {
                log.debug("Creating a DBCP BasicDataSource with the following DBCP factory properties:");
                StringWriter sw = new StringWriter();
                dbcpProperties.list(new PrintWriter(sw, true));
                log.debug(sw.toString());
            }
            // Let the factory create the pool
            ds = (BasicDataSource) BasicDataSourceFactory.createDataSource(dbcpProperties);
         
            // The BasicDataSource has lazy initialization
            // borrowing a connection will start the DataSource
            // and make sure it is configured correctly.
            Connection conn = ds.getConnection();
            conn.close();
            // Log pool statistics before continuing.
            logStatistics();
        }
        catch (Exception e) {
            String message = "Could not create a DBCP pool";
            log.fatal(message, e);
            if (ds != null) {
                try {
                    ds.close();
                }
                catch (Exception e2) {
                    // ignore
                }
                ds = null;
            }
            throw new HibernateException(message, e);
        }
        log.debug("Configure DBCPConnectionProvider complete");
    }
    public Connection getConnection() throws SQLException {
        Connection conn = null;
        try {
         //log.warn(" Get connection called");
                conn = ds.getConnection();
        }
        finally {
            logStatistics();
        }
        return conn;
    }
    public void closeConnection(Connection conn) throws SQLException {
        try {
   conn.commit(); //Test ***********
       
            conn.close();
            //log.warn("Is Connection closed "+conn.isClosed());
        }
        catch(Exception e) {
         e.printStackTrace();
         log.warn("Error While commit/close concetion",e);
         if(!conn.isClosed())
         {
          log.warn("check point in dbcp 1");
          conn.close();
         }
        }
        finally {
         if(!conn.isClosed()) {
          log.warn("check point in dbcp 2");
          conn.close();
         }
            logStatistics();
        }
    }
    public void close() throws HibernateException {
        try {
            if (ds != null) {
                ds.close();
                    ds = null;
            }
            else {
                log.warn("Cannot close DBCP pool (not initialized)");
            }
        }
        catch (Exception e) {
            throw new HibernateException("Could not close DBCP pool", e);
        }
        log.debug("Close DBCPConnectionProvider complete");
    }
 
        public boolean supportsAggressiveRelease() {
        return true; //It was false ****************
    }
}