Pages

Wednesday, October 20, 2010

Hibernate Mapping File

Object/relational mappings are usually defined in an XML document. The mapping document is designed to be readable and hand-editable. The mapping language is Java-centric, meaning that mappings are constructed around persistent class declarations and not table declarations.


Please note that even though many Hibernate users choose to write the XML by hand, a number of tools exist to generate the mapping document. These include XDoclet, Middlegen and AndroMDA.
Here is an example mapping:
<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="eg">


        <class name="Cat"
            table="cats"
            discriminator-value="C">
                <id name="id">
                        <generator class="native"/>
                </id>
                <discriminator column="subclass"
                     type="character"/>
                <property name="weight"/>
                <property name="birthdate"
                    type="date"
                    not-null="true"
                    update="false"/>
                <property name="color"
                    type="eg.types.ColorUserType"
                    not-null="true"
                    update="false"/>
                <property name="sex"
                    not-null="true"
                    update="false"/>
                <property name="litterId"
                    column="litterId"
                    update="false"/>
                <many-to-one name="mother"
                    column="mother_id"
                    update="false"/>
                <set name="kittens"
                    inverse="true"
                    order-by="litter_id">
                        <key column="mother_id"/>
                        <one-to-many class="Cat"/>
                </set>
                <subclass name="DomesticCat"
                    discriminator-value="D">
                        <property name="name"
                            type="string"/>
                </subclass>


        </class>


        <class name="Dog">
                <!-- mapping for Dog could go here -->
        </class>


</hibernate-mapping>

Doctype

All XML mappings should declare the doctype shown. The actual DTD can be found at the URL above, in 
the directory hibernate-x.x.x/src/org/hibernate , or in hibernate3.jar. Hibernate will always look for the DTD in its classpath first. If you experience lookups of the DTD using an Internet connection, check the DTD declaration against the contents of your classpath.


EntityResolver


Hibernate will first attempt to resolve DTDs in its classpath. It does this is by registering a customorg.xml.sax.EntityResolver implementation with the SAXReader it uses to read in the xml files. This customEntityResolver recognizes two different systemId namespaces:
  • hibernate namespace is recognized whenever the resolver encounters a systemId starting withhttp://hibernate.sourceforge.net/. The resolver attempts to resolve these entities via the classloader which loaded the Hibernate classes.
  • user namespace is recognized whenever the resolver encounters a systemId using a classpath:// URL protocol. The resolver will attempt to resolve these entities via (1) the current thread context classloader and (2) the classloader which loaded the Hibernate classes.
The following is an example of utilizing user namespacing:
<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" [
    <!ENTITY types SYSTEM "classpath://your/domain/types.xml">
]>


<hibernate-mapping package="your.domain">
    <class name="MyEntity">
        <id name="id" type="my-custom-id-type">
            ...
        </id>
    <class>
    &types;
</hibernate-mapping>



Hibernate-mapping

This element has several optional attributes. The schema and catalog attributes specify that tables referred to in this mapping belong to the named schema and/or catalog. If they are specified, tablenames will be qualified by the given schema and catalog names. If they are missing, tablenames will be unqualified. The default-cascade attribute specifies what cascade style should be assumed for properties and collections that do not specify a cascade attribute. By default, the auto-import attribute allows you to use unqualified class names in the query language.


<hibernate-mapping

         schema="schemaName"                           
         catalog="catalogName"                         
         default-cascade="cascade_style"               
         default-access="field|property|ClassName"     
         default-lazy="true|false"                     
         auto-import="true|false"                      
         package="package.name"                        
 />

schema (optional): the name of a database schema.
catalog (optional): the name of a database catalog.
default-cascade (optional - defaults to none): a default cascade style.
default-access (optional - defaults to property): the strategy Hibernate should use for accessing all properties. It can be a custom implementation of PropertyAccessor.
default-lazy (optional - defaults to true): the default value for unspecified lazy attributes of class and collection mappings.
auto-import (optional - defaults to true): specifies whether we can use unqualified class names of classes in this mapping in the query language.
package (optional): specifies a package prefix to use for unqualified class names in the mapping document.

If you have two persistent classes with the same unqualified name, you should set auto-import="false". An exception will result if you attempt to assign two classes to the same "imported" name.
The hibernate-mapping element allows you to nest several persistent  mappings, as shown above. It is, however, good practice (and expected by some tools) to map only a single persistent class, or a single class hierarchy, in one mapping file and name it after the persistent superclass. For example,Cat.hbm.xmlDog.hbm.xml, or if using inheritance, Animal.hbm.xml.


Class

You can declare a persistent class using the class element. For example:
<class

        name="ClassName"                              
        table="tableName"                             
        discriminator-value="discriminator_value"     
        mutable="true|false"                          
        schema="owner"                                
        catalog="catalog"                             
        proxy="ProxyInterface"                        
        dynamic-update="true|false"                   
        dynamic-insert="true|false"                   
        select-before-update="true|false"             
        polymorphism="implicit|explicit"              
        where="arbitrary sql where condition"         
        persister="PersisterClass"                    
        batch-size="N"                                
        optimistic-lock="none|version|dirty|all"      
        lazy="true|false"                            
        entity-name="EntityName"                  
        check="arbitrary sql check condition"     
        rowid="rowid"                              
        subselect="SQL expression"               
        abstract="true|false"                      
        node="element-name"
/>



name (optional): the fully qualified Java class name of the persistent class or interface. If this attribute is missing, it is assumed that the mapping is for a non-POJO entity.
table (optional - defaults to the unqualified class name): the name of its database table.
discriminator-value (optional - defaults to the class name): a value that distinguishes individual subclasses that is used for polymorphic behavior. Acceptable values include null and not null.
mutable (optional - defaults to true): specifies that instances of the class are (not) mutable.
schema (optional): overrides the schema name specified by the root <hibernate-mapping> element.
catalog (optional): overrides the catalog name specified by the root <hibernate-mapping> element.
proxy (optional): specifies an interface to use for lazy initializing proxies. You can specify the name of the class itself.
dynamic-update (optional - defaults to false): specifies that UPDATE SQL should be generated at runtime and can contain only those columns whose values have changed.
dynamic-insert (optional - defaults to false): specifies that INSERT SQL should be generated at runtime and contain only the columns whose values are not null.
select-before-update (optional - defaults to false): specifies that Hibernate should never perform an SQL UPDATE unless it is certain that an object is actually modified. Only when a transient object has been associated with a new session using update(), will Hibernate perform an extra SQL SELECT to determine if an UPDATE is actually required.
polymorphism (optional - defaults to implicit): determines whether implicit or explicit query polymorphism is used.
where (optional): specifies an arbitrary SQL WHERE condition to be used when retrieving objects of this class.
persister (optional): specifies a custom ClassPersister.
batch-size (optional - defaults to 1): specifies a "batch size" for fetching instances of this class by identifier.
optimistic-lock (optional - defaults to version): determines the optimistic locking strategy.
lazy (optional): lazy fetching can be disabled by setting lazy="false".
entity-name (optional - defaults to the class name): Hibernate3 allows a class to be mapped multiple times, potentially to different tables. It also allows entity mappings that are represented by Maps or XML at the Java level. In these cases, you should provide an explicit arbitrary name for the entity. 
check (optional): an SQL expression used to generate a multi-row check constraint for automatic schema generation.
rowid (optional): Hibernate can use ROWIDs on databases. On Oracle, for example, Hibernate can use the rowid extra column for fast updates once this option has been set to rowid. A ROWID is an implementation detail and represents the physical location of a stored tuple.
subselect (optional): maps an immutable and read-only entity to a database subselect. This is useful if you want to have a view instead of a base table. See below for more information.
abstract (optional): is used to mark abstract superclasses in <union-subclass> hierarchies



id

Mapped classes must declare the primary key column of the database table. Most classes will also have a JavaBeans-style property holding the unique identifier of an instance. The  element defines the mapping from that property to the primary key column.

<id
        name="propertyName"                                        
        type="typename"                                            
        column="column_name"                                        
        unsaved-value="null|any|none|undefined|id_value"            
        access="field|property|ClassName">                          
        node="element-name|@attribute-name|element/@attribute|."

        <generator class="generatorClass"/>
</id>

name (optional): the name of the identifier property.
type (optional): a name that indicates the Hibernate type.
column (optional - defaults to the property name): the name of the primary key column.
unsaved-value (optional - defaults to a "sensible" value): an identifier property value that indicates an instance is newly instantiated (unsaved), distinguishing it from detached instances that were saved or loaded in a previous session.
access (optional - defaults to property): the strategy Hibernate should use for accessing the property value.

If the name attribute is missing, it is assumed that the class has no identifier property.
The unsaved-value attribute is almost never needed in Hibernate3.
There is an alternative <composite-id> declaration that allows access to legacy data with composite keys. Its use is strongly discouraged for anything else.


Generator

The optional  child element names a Java class used to generate unique identifiers for instances of the persistent class. If any parameters are required to configure or initialize the generator instance, they are passed using the 
 element.

All generators implement the interface org.hibernate.id.IdentifierGenerator. This is a very simple interface. Some applications can choose to provide their own specialized implementations, however, Hibernate provides a range of built-in implementations. The shortcut names for the built-in generators are as follows:

increment
generates identifiers of type longshort 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 longshort or int.
sequence
uses a sequence in DB2, PostgreSQL, Oracle, SAP DB, McKoi or a generator in Interbase. The returned identifier is of type longshort or int
hilo
uses a hi/lo algorithm to efficiently generate identifiers of type longshort or int, given a table and column (by default hibernate_unique_key and next_hi respectively) as a source of hi values. The hi/lo algorithm generates identifiers that are unique only for a particular database.
seqhilo
uses a hi/lo algorithm to efficiently generate identifiers of type longshort or int, given a named database sequence.
uuid
uses a 128-bit UUID algorithm to generate identifiers of type string that are unique within a network (the IP address is used). The UUID is encoded as a string of 32 hexadecimal digits in length.
guid
uses a database-generated GUID string on MS SQL Server and MySQL.
native
selects identitysequence or hilo depending upon the capabilities of the underlying database.
assigned
lets the application assign an identifier to the object before save() is called. This is the default strategy if no  element is specified.
select
retrieves a primary key, assigned by a database trigger, by selecting the row by some unique key and retrieving the primary key value.
foreign
uses the identifier of another associated object. It is usually used in conjunction with a primary key association.
sequence-identity

    a specialized sequence generation strategy that utilizes a database sequence for the actual value generation, but combines this with JDBC3 getGeneratedKeys to return the generated identifier value as part of the insert statement execution. This strategy is only supported on Oracle 10g drivers targeted for JDK 1.4. Comments on these insert statements are disabled due to a bug in the Oracle drivers.


composite-id

<composite-id
        name="propertyName"
        class="ClassName"
        mapped="true|false"
        access="field|property|ClassName">
        node="element-name|."
        <key-property name="propertyName" type="typename" column="column_name"/>
        <key-many-to-one name="propertyName class="ClassName" column="column_name"/>
        ......
</composite-id>










Saturday, October 16, 2010

Hibernate Basics


As a persistence service, Hibernate must work with multiple databases and within various application environments. Supporting these variations requires Hibernate to be highly configurable to adapt to different environments. After all, running a standalone application can be quite different from running a web application. Differences in obtaining database connections, for instance, can be significant. Hibernate is typically configured in two steps.

First, you configure the Hibernate service. This includes database connection parameters, caching, and the collection of persistent classes man–aged by Hibernate. Second, you must provide Hibernate with information about the classes to be persisted. Persistent class configuration allows you to bridge gaps between the class and databases.


Although it's commonly used within J2EE application servers, such as WebSphere and JBoss, Hibernate can also be used in standalone applications. Requirements vary for different environments, and Hibernate can be configured to adapt to them. Hibernate works with various support services, such as connection pools, caching services, and transaction managers. It also lets you maintain additional support services by implementing simple interfaces.


Hibernate supports a number of different configuration methods and options to support these scenarios. Configuring all of Hibernate's properties can be overwhelming, so we'll start slowly. Before we jump into configuration, look at figure , which shows the major Hibernate classes and configuration files.


The light gray boxes in the figure are the classes your application code will use most often. The dark gray boxes are the configuration files used by the Configuration class to create the SessionFactory , which in turn creates the Session instances. Session instances are your primary interface to the Hibernate persistence service.

SessionFactory

The SessionFactory is created from a Configuration object, and as its name implies it is a factory for Session objects.


Configurer c = new Configurer();
// load XML file and parse the XML file
c.confgurer(“/hibernate.cfg.xml”);
//the entire XML file data is stored in sessionFactory class object. Infact SessionFactory class is a representation of hibernate.cfg.xml file
SessionFactory sf = c.buildSessionFactory();


The SessionFactory is an expensive object to create. It, like the Configuration object, is usually created during application start up. However, unlike the Configuration object, It should be created once and kept for later use.


The SessionFactory object is used by all the threads of an application. It is a thread safe object. One SessionFactory object is created per database. Multiple SessionFactory objects (each requiring a separate Configuration) are created when connecting to multiple databases. The SessionFactory can also provide caching of persistent objects.

Session


A Hibernate Session object represents a single unit-of-work for a given data store and is opened by a SessionFactory instance. You must close Sessions when all work for a transaction is completed.

A single-threaded, short lived object representing a conversation between the application and the persistent store.

Wraps a JDBC connection factory for transaction, For each client request create a session object and destroy after the task (session.close()).

SessionFactory.openSession() method creates one Session object, means when openSession() method is requested one database connection object is created and internally assigned to Session object. Session means internally it is a JDBC Connection object.

Session s = sf.openSession();

Hibernate internally saves every object into session cache first and then converts into sql operation and that too SQL operation is not immediately executed on database first they are all added into Statements batch and then executes the batch.

After creating the Session object, create one java Bean object.

Customer c = new Customer();
c.setID(1);
c.setName(“Vardhan”);
s.save(c);
s.flush();
t.commit();

Session object first stores customer object into one collection object with id as key, and then convert’s customer object into SQL statement/INSERT statement. The insert statement is added to batch.

Whenever s.flush() method is called, flush() method is equal to statement.executeBatch() method. It flushes all SQL statements to DB. And when finally t.commit() method is called, DB permanently stores the record into DB.