Sunteți pe pagina 1din 28

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 1 of 28 What is ORM?................................................................................................................1 Hibernate Types.........................................................................................................

8 Important Mappings .....................................................................................................9 Collection Mapping......................................................................................................14 Associations..............................................................................................................15 Inheritance mapping Strategies.................................................................................21 Hibernate Query Language......................................................................................23 Criteria Query...............................................................................................................27 SecondLevel cache...................................................................................................28

What is ORM?
object/relational mapping is the automated persistence of objects in a Java application to the tables in a relational database, using metadata that describes the mapping between the objects and the database. ORM works by transforming data from object representation to relational representation in RDBMS. The mapping of objects to the tables in the database is specified in hbm.xml files. An ORM solution provides 1. An API for performing basic CRUD operations on objects of persistent classes. 2. An API for writing queries that refer to classes and properties of classes 3. A means to specify mapping metadata

Advantages of Hibernate/ORM
Productivity : Java developers spend most of their on writing jdbc code rather than on application logic. Since, Hibernate takes most of the responsibility of the persistence code, java developer can focus more on the business problem. Maintainability : Since, most of the code related to persistence is generated by ORM at the run time, it reduces the size of the code. Small code base is easy to maintain and refactor. Performance: Hibernate comes with many optimizations to the persistence code. A developer, instead of fine tuning the performance by hand, can use the optimizations provided by Hibernate. Database independence : Irrespective of the different types of databases that are there, hibernate provides a much easier way to develop a cross platform application. Optimistic Transactions : Hibernate provides out-of-box support for optimistic transaction for long running transactions. Caching : Hibernate provides elegant solutions for data caching. Caching the read-only data gives significant perfromance boost for the application.

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 2 of 28

Hibernate Architecture

Hibernate Configuration File: Hibernate environment can be configured in a couple of ways. One standard way that proves very flexible and convenient is to store the configuration in a file named hibernate.cfg.xml. This configuration file is placed in the classpath of the application. Hibernate.cfg.xml file can be accessed and read using the org.hibernate.cfg.Configuration class at runtime. The hibernate.cfg.xml file defines information about the database connection, the transaction factory class, resource mappings, etc. <?xml version="1.0"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernateconfiguration-3.0.dtd">

<hibernate-configuration>

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 3 of 28

<session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property> <property name="connection.username">root</property> <property name="connection.password"></property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.current_session_context_class">thread</property> <property name="show_sql">true</property> <mapping resource="parent.hbm.xml"/> </session-factory> </hibernate-configuration> Programming : With hibernate.cfg.xml starting hibernate is easy. Assuming the cfg.xml file is in class path,
SessionFactory sf = new Configuration().configure().buildSessionFactory(); Configuration file which has different name can be picked using SessionFactory sf = new Configuration().configure(krsnatcube.cfg.xml).buildSessionFactory(); The Hibernate Mapping Configuration File Hibernate applications make use of mapping files containing metadata defining object/relational mappings for Java classes. A mapping file is designated with a suffix of .hbm.xml. Within each configuration file, classes to be made persistent are mapped to database tables and properties are defined which map class-fields to columns and primary keys. 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, not table declarations. <?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="learn" default-access="property"> <class name="Parent" table="parent" check="age > 15"> <id name="id" column="testid" type="integer"> <generator class="native"/> </id> <version name="versionid" />

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 4 of 28 <property name="firstName" column="FirstName"/> <property name="lastName" unique="false" /> <property name="age" type="double"> <column name="colage" sql-type="decimal(10,3)" /> </property> <property name="birthDate" column="dob" type="timestamp" /> </class>

</hibernate-mapping>
A number of tools exist to generate the mapping document, including XDoclet, Middlegen and AndroMDA. Lets discuss the various elements of the hibernate-mapping file <hibernate-mapping schema="schemaName" (1) default-cascade="cascade_style" (3) default-access="field|property|ClassName" (4) default-lazy="true|false" (5) package="package.name" (7) /> schema (optional): The name of a database schema. 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. default-lazy (optional - defaults to true): The default value for unspecifed lazy attributes of class and collection mappings. package (optional): Specifies a package prefix to assume for unqualified class names in the mapping document. <class name="ClassName" table="tableName" dynamic-update="true|false" dynamic-insert="true|false" batch-size="N" lazy= true/false where="arbitrary sql where condition" optimistic-lock="none|version|dirty|all" /> 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. dynamic-update (optional, defaults to false): Specifies that UPDATE SQL should be generated at runtime and contain only those columns whose values have changed.

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 5 of 28 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. batch-size (optional, defaults to 1) specify 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 may be completely disabled by setting lazy="false".

Id:
Mapped classes must declare the primary key column of the database table.The <id> element defines the mapping from that property to the primary key column. <id name="propertyName" type="typename" column="column_name" <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.
Generator

The optional <generator> 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 <param> element. <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> Hibernate provides a range of built-in implementations. There are shortcut names for the built-in generators: 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">

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 6 of 28 <generator class="sequence"> <param name="sequence">employer_id_seq</param> </generator>
</id>

uuid uses a 128-bit UUID algorithm to generate identifiers of type string, unique within a network (the IP address is used). The UUID is encoded as a string of hexadecimal digits of length 32. guid uses a database-generated GUID string on MS SQL Server and MySQL. hilo uses a hi/lo algorithm to efficiently generate identifiers of type long, short 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. <id name="id" type="long" column="cat_id"> <generator class="hilo"> <param name="table">hi_value</param> <param name="column">next_value</param> <param name="max_lo">100</param> </generator> </id> native picks identity, sequence or hilo depending upon the capabilities of the underlying database. assigned lets the application to assign an identifier to the object before save() is called. This is the default strategy if no <generator> element is specified.

Property:
<property name="propertyName" column="column_name" type="typename" update="true|false" insert="true|false" lazy="true|false" unique="true|false" not-null="true|false" optimistic-lock="true|false" /> name: the name of the property, with an initial lowercase letter

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 7 of 28 column (optional - defaults to the property name): the name of the mapped database table column. This may also be specified by nested <column> element(s). type (optional): a name that indicates the Hibernate type. update, insert (optional - defaults to true) : specifies that the mapped columns should be included in SQL UPDATE and/or INSERT statements unique (optional): Enable the DDL generation of a unique constraint for the columns. Also, allow this to be the target of a property-ref. not-null (optional): Enable the DDL generation of a nullability constraint for the columns. optimistic-lock (optional - defaults to true): Specifies that updates to this property do or do not require acquisition of the optimistic lock. In other words, determines if a version increment should occur when this property is dirty. Component : The term "component" refers to the object-oriented notion of composition. A component has no individual identity, hence the persistent component class requires no identifier property or identifier mapping. Its a simple POJO: Hibernate uses the term component for a user-defined class that is persisted to the same table as the owning entity. <component name="propertyName" class="className" > <property name= column= type=/> <property name= column= type=/> </component>

Hibernate object states


Hibernate defines and supports the following object states:

Transient - an object is transient if it has just been instantiated using the


new operator, and it is not associated with a Hibernate Session. It has no persistent representation in the database and no identifier value has been assigned. Transient instances will be destroyed by the garbage collector if the application doesn't hold a reference anymore. Use the Hibernate Session to make an object persistent (and let Hibernate take care of the SQL statements that need to be executed for this transition). Persistent - a persistent instance has a representation in the database and an identifier value. It might just have been saved or loaded; however, it is still in the scope of a Session. Hibernate will detect any changes made to an object in persistent state and synchronize the state with the database when the unit of work completes.(transitive persistence) . Any changes made to the object in persistent state are automatically updated during transaction time.

Detached - A detached instance is an object that has been persistent, but


its Session has been closed. The reference to the object is still valid, of course, and the detached instance might even be modified in this state. A detached instance can be reattached to a new Session at a later point in time, making it (and all the modifications) persistent again. This feature enables a

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 8 of 28 programming model for long running units of work that require user think-time. These are called application transactions, i.e. a unit of work from the point of view of the user.

Automatic dirty checking: Inside a transaction, if changes are


made to the state of the persistent object, there is no need to explicitly call the session.update() , the modified state is committed to the database at the transaction commit time. As long as the object is in persistent state that is, bound to a particular Hibernate Session (i.e. they have been just loaded or saved in a unit of work), Hibernate detects any changes to the persistent entity state and executes SQL in a write-behind fashion. The process of synchronizing the memory state with the database, usually only at the end of a unit of work, is called flushing Session session = sessions.openSession(); Transaction tx = session.beginTransaction(); Person person = (Person) session.get(Person.class, new Long(userID)); person.setPassword("secret"); tx.commit(); // we are not invoking update() method. dirty checking session.close(); Hibernate Types To understand the behaviour of various Java language-level objects with respect to the persistence service, we need to classify them into two groups: Entity Type: An object of entity type has its own database identity (primary key value). An object reference to an entity is persisted as a reference in the database (a foreign key value). An entity has its own lifecycle; it may exist independently of any other entity. The entity types are shared( when loaded from database) Entities must be explicitly saved and deleted (except that saves and deletions may be cascaded from a parent entity to its children). An entity's persistent state consists of references to other entities and instances of value types. Value Type: An object of value type has no database identity; it belongs to an entity, and its persistent state is embedded in the table row of the owning entity. Value types dont have identifiers or identifier properties. The lifespan of a valuetype instance is bounded by the lifespan of the owning entity. Value types are not shared. A value type instance is owned by exactly one entity when its retrieved from the database its never shared. Values are primitives, collections (not what's inside a collection), components and certain immutable objects. all types (classes) provided by the JDK have value type semantics in Java, while user-defined types may be mapped with entity or value type semantics

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 9 of 28

Basic value types


The built-in basic mapping types may be roughly categorized into integer, long, short, float, double, character, byte, boolean, yes_no, true_false Type mappings from Java primitives or wrapper classes to appropriate (vendor-specific) SQL column types. boolean, yes_no and true_false are all alternative encodings for a Java boolean or java.lang.Boolean. string A type mapping from java.lang.String to VARCHAR (or Oracle VARCHAR2). date, time, timestamp Type mappings from java.util.Date and its subclasses to SQL types DATE, TIME and TIMESTAMP (or equivalent). calendar, calendar_date Type mappings from java.util.Calendar to SQL types TIMESTAMP and DATE (or equivalent). big_decimal, big_integer Type mappings from java.math.BigDecimal and java.math.BigInteger to NUMERIC (or Oracle NUMBER). locale, timezone, currency Type mappings from java.util.Locale, java.util.TimeZone and java.util.Currency to VARCHAR (or Oracle VARCHAR2). Instances of Locale and Currency are mapped to their ISO codes. Instances of TimeZone are mapped to their ID class A type mapping from java.lang.Class to VARCHAR (or Oracle VARCHAR2). A Class is mapped to its fully qualified name. binary Maps byte arrays to an appropriate SQL binary type. text Maps long Java strings to a SQL CLOB or TEXT type. serializable Maps serializable Java types to an appropriate SQL binary type. You may also indicate the Hibernate type serializable with the name of a serializable Java class or interface that does not default to a basic type. clob, blob Type mappings for the JDBC classes java.sql.Clob and java.sql.Blob. These types may be inconvenient for some applications, since the blob or clob object may not be reused outside of a transaction. (Furthermore, driver support is patchy and inconsistent.)

Important Mappings

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 10 of 28

many-to-one: An ordinary association to another persistent class is


declared using a many-to-one element. The relational model is a many-to-one association: a foreign key in one table is referencing the primary key column(s) of the target table. <many-to-one name="propertyName" column="column_name" class="ClassName" cascade="cascade_style" fetch="join|select" update="true|false" insert="true|false" property-ref="propertyNameFromAssociatedClass" unique="true|false" (9) not-null="true|false" (10) lazy="proxy|no-proxy|false" unique_key="unique_key_id" foreign-key="foreign_key_name" /> name: The name of the property. column (optional): The name of the foreign key column. This may also be specified by nested <column> element(s). class (optional - defaults to the property type determined by reflection): The name of the associated class. cascade (optional): Specifies which operations should be cascaded from the parent object to the associated object. update, insert (optional - defaults to true) specifies that the mapped columns should be included in SQL UPDATE and/or INSERT statements. Setting both to false allows a pure "derived" association whose value is initialized from some other property that maps to the same colum(s) or by a trigger or other application. property-ref: (optional) The name of a property of the associated class that is joined to this foreign key. If not specified, the primary key of the associated class is used. unique (optional): Enable the DDL generation of a unique constraint for the foreign-key column. Also, allow this to be the target of a property-ref. This makes the association multiplicity effectively one to one. not-null (optional): Enable the DDL generation of a nullability constraint for the foreign key columns.

composite-id
<composite-id name=id class=PersonId> <key-property name="firstname"/> <key-property name="lastname"/> </composite-id>

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 11 of 28 For a table with a composite key, you may map multiple properties of the class as identifier properties. The <composite-id> element accepts <keyproperty> property mappings as child elements. Your persistent class must override equals() and hashCode() to implement composite identifier equality. It must also implements Serializable.

one-to-one
A one-to-one association to another persistent class is declared using a oneto-one element. <one-to-one name="propertyName" class="ClassName" cascade="cascade_style" fetch="join|select" property-ref="propertyNameFromAssociatedClass" lazy="proxy|no-proxy|false" foreign-key="foreign_key_name" /> name: The name of the property. class (optional - defaults to the property type determined by reflection): The name of the associated class. cascade (optional) specifies which operations should be cascaded from the parent object to the associated object. fetch (optional - defaults to select): Chooses between outer-join fetching or sequential select fetching. property-ref: (optional) The name of a property of the associated class that is joined to the primary key of this class. If not specified, the primary key of the associated class is used. access (optional - defaults to property): The strategy Hibernate should use for accessing the property value. lazy (optional - defaults to proxy): By default, single point associations are proxied. lazy="no-proxy" specifies that the property should be fetched lazily when the instance variable is first accessed (requires build-time bytecode instrumentation). lazy="false" specifies that the association will always be eagerly fetched.

subclass
For the table-per-class-hierarchy mapping strategy, the <subclass> declaration is used. <subclass name="ClassName" discriminator-value="discriminator_value" lazy="true|false" dynamic-update="true|false" dynamic-insert="true|false" extends="SuperclassName">

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 12 of 28 <property .... /> ..... </subclass> name: The fully qualified class name of the subclass. discriminator-value (optional - defaults to the class name): A value that distiguishes individual subclasses. lazy (optional, defaults to true): Setting lazy="false" disables the use of lazy fetching. Each subclass should declare its own persistent properties and subclasses. <version> and <id> properties are assumed to be inherited from the root class. Each subclass in a heirarchy must define a unique discriminatorvalue. If none is specified, the fully qualified Java class name is used.

joined-subclass
Each subclass may be mapped to its own table (table-per-subclass mapping strategy). Inherited state is retrieved by joining with the table of the superclass. We use the <joined-subclass> element. <joined-subclass name="ClassName" (1) table="tablename" (2) lazy="true|false" (4) dynamic-update="true|false" dynamic-insert="true|false" schema="schema" extends="SuperclassName" > <key > <property .... /> ..... </joined-subclass> name: The fully qualified class name of the subclass. table: The name of the subclass table. proxy (optional): Specifies a class or interface to use for lazy initializing proxies. lazy (optional, defaults to true): Setting lazy="false" disables the use of lazy fetching No discriminator column is required for this mapping strategy. Each subclass must, however, declare a table column holding the object identifier using the <key> element.

union-subclass

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 13 of 28 A third option is to map only the concrete classes of an inheritance hierarchy to tables, (the table-per- concrete-class strategy) where each table defines all persistent state of the class, including inherited state. In Hibernate, it is not absolutely necessary to explicitly map such inheritance hierarchies. You can simply map each class with a separate <class> declaration. However, if you wish use polymorphic associations (e.g. an association to the superclass of your hierarchy), you need to use the <union-subclass> mapping. <union-subclass name="ClassName" table="tablename" proxy="ProxyInterface" lazy="true|false" extends="SuperclassName" abstract="true|false" > <property .... /> </union-subclass> name: The fully qualified class name of the subclass. table: The name of the subclass table. proxy (optional): Specifies a class or interface to use for lazy initializing proxies. lazy (optional, defaults to true): Setting lazy="false" disables the use of lazy fetching. No discriminator column or key column is required for this mapping strategy.

join
Using the <join> element, it is possible to map properties of one class to several tables.

<join table="tablename" schema="owner" optional="true|false"> <key ... /> <property ... /> ... </join> table: The name of the joined table. optional (optional - defaults to false): If enabled, Hibernate will insert a row only if the properties defined by this join are non-null and will always use an outer join to retrieve the properties. <class name="Person" table="PERSON"> <id name="id" column="PERSON_ID">...</id> <join table="ADDRESS">

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 14 of 28 <key column="ADDRESS_ID"/> <property name="address"/> <property name="zip"/> <property name="country"/> </join>

key
It appears in the parent mapping element defines a join to a new table, and defines the foreign key in the joined table, that references the primary key of the original table. <key column="columnname" on-delete="noaction|cascade" property-ref="propertyName" not-null="true|false" update="true|false" unique="true|false" /> column (optional): The name of the foreign key column. This may also be specified by nested <column> element(s). on-delete (optional, defaults to noaction): Specifies whether the foreign key constraint has databaselevel cascade delete enabled. property-ref (optional): Specifies that the foreign key refers to columns that are not the primary key of the orginal table. (Provided for legacy data.) not-null (optional): Specifies that the foreign key columns are not nullable (this is implied whenever the foreign key is also part of the primary key). update (optional): Specifies that the foreign key should never be updated (this is implied whenever the foreign key is also part of the primary key). unique (optional): Specifies that the foreign key should have a unique constraint (this is implied whenever the foreign key is also the primary key).

Collection Mapping
Persistent collections
Hibernate requires that persistent collection-valued fields be declared as an interface type, for example: public class Product { private String serialNumber; private Set parts = new HashSet(); public Set getParts() { return parts; } void setParts(Set parts) { this.parts = parts;

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 15 of 28 } public String getSerialNumber() { return serialNumber; } void setSerialNumber(String sn) { serialNumber = sn; } } The actual interface might be java.util.Set, java.util.Collection, java.util.List, java.util.Map, java.util.SortedSet, java.util.SortedMap Collections instances have the usual behavior of value types. They are automatically persisted when referenced by a persistent object and automatically deleted when unreferenced. If a collection is passed from one persistent object to another, its elements might be moved from one table to another.

Collection foreign keys


Collection instances are distinguished in the database by the foreign key of the entity that owns the collection. This foreign key is referred to as the collection key column (or columns) of the collection table. The collection key column is mapped by the <key> element. There may be a nullability constraint on the foreign key column. For most collections, this is implied. For unidirectional one to many associations, the foreign key column is nullable by default, so you might need to specify not-null="true". <class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <set name="addresses" table=address> <key column="personId" /> <one-to-many class="Address"/> </set> </class> Here, <key> represents foreign key column in address table which refers to the primary key personid of the person table

Associations One-to-many association unidirectional


A one to many association links the tables of two classes via a foreign key, with no intervening collection table.

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 16 of 28 <one-to-many class="ClassName" /> class (required): The name of the associated class. <one-to-many> element does not need to declare any columns. Nor is it necessary to specify the table name anywhere. <class name="Person"> <id name="id" column="personId"> <generator class="increment"/> </id> <set name="addresses"> <key column="personId" /> <one-to-many class="Address"/> </set> </class> <class name="Address"> <id name="id" column="addressId"> <generator class="increment"/> </id> </class>

many to one uni-directional


<class name="Person"> <id name="id" column="personId"> <generator class="increment"/> </id> <many-to-one name="address" column="addressId" /> </class> <class name="Address"> <id name="id" column="addressId"> <generator class="increment"/> </id> </class>

one to one unidirectional


A unidirectional one-to-one association on a foreign key is almost identical. The only difference is the column unique constraint. <class name="Person"> <id name="id" column="personId"> <generator class="increment"/> </id>

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 17 of 28 <many-to-one name="address" column="addressId" not-null="true" unique=true/> </class> <class name="Address"> <id name="id" column="addressId"> <generator class="increment"/> </id> </class> making associations bidirectional Object-oriented languages represent associations using object references and collections of object references. In the relational world, an association is represented as a foreign key column, Object references are inherently directional; the association is from one object to the other. If an association between objects should be navigable in both directions, you must define the association twice, once in each of the associated classes class person{ private Address address; ---} class Address{ private Person person; } On the other hand, foreign key associations arent by nature directional. In fact, navigation has no meaning for a relational data model, because you can create arbitrary data associations with table joins and projection. In order to make a relation bi-directional the following changes are necessary. Lets take the example, person & address bi-directional one-tomany relation <class name="Person"> <id name="id" column="personId"> <generator class="increment"/> </id> <set name="addresses" inverse="true"> <key column="addressId"/> <one-to-many class="Person"/> </set> </class>

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 18 of 28 <class name="Address"> <id name="id" column="addressId"> <generator class="increment"/> </id> <many-to-one name="person" column="addressId" not-null="true"/> </class> 1) Java code.: There should be references from person to address and address to person. 2) hbm.xml : The column mapping defined by the <key> element in <set> is foreign key column of the associated address table. Notice that in the mapping for the many-to-one association we specified same column as foreign key column. Now we have two different unidirectional associations mapped to the same foreign key, which poses a problem. At runtime, there are two different inmemory representations of the same foreign key value: the Person property of Address and an element of the address collection held by an person. Now, our TestMain class has code like this, addresses.add(address); address.setPerson(person); Hibernate detects two different changes to the in-memory persistent instances. From the point of view of the database, just one value must be updated to reflect these changes: the personid column of the BID table. Hibernate doesnt transparently detect the fact that the two changes refer to the same database column, since at this point weve done nothing to indicate that this is a bidirectional association. We need one more thing in our association mapping to tell Hibernate to treat this as a bidirectional association: The inverse attribute tells Hibernate that the collection is a mirror image of the many-to-one association on the other side: <set name="bids" inverse="true"> <key column="ITEM_ID"/> </set> Without the inverse attribute, Hibernate would try to execute two different SQL statements, both updating the same foreign key column, when we manipulate the association between the two instances. By specifying inverse="true", we explicitly tell Hibernate which end of the association it should synchronize with the database. In this example, we tell Hibernate that it should propagate changes made at the Address end of the association to the database, ignoring changes made only to the address collection on the person side. Thus if we only call person.getAddresses().add(address), no changes will be made persistent. This is consistent with the behavior in Java without Hibernate: If an association is bidirectional, you have to create the link on two

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 19 of 28 sides, not just one.

one to one bi-directional


<class name="Person"> <id name="id" column="personId"> <generator class="increment"/> </id> <many-to-one name="address" column="addressId" unique="true" not-null="true"/> </class> <class name="Address"> <id name="id" column="addressId"> <generator class="increment"/> </id> <one-to-one name="person" property-ref="address"/> </class> property-ref: (optional) The name of a property of the associated class that is joined to the primary key of this class. If not specified, the primary key of the associated class is used.

many-to-many unidirectional
One Category has many items and one item has many categories. Many-tomany association always require a link table. In this association, there would be 3 tables, one for category, one for item and third table is a link table category_item. Link table consists of the two columns categoryid and itemid. Categoryid has foreign key relation to primary key of the category table. itemid has the foreign key relation to the primary key of the Item table. The primary key of the link table is composed of both columns in link table.

<class name="Category" table="CATEGORY"> <id name="id" type="long" column="CATEGORY_ID"> <generator class="increment"/> </id> <version name="version" column="OBJ_VERSION"/> <property name="name" type="string"> <column name="CATEGORY_NAME" not-null="true" length="255"/> </property> <set name="items" cascade="all,delete-orphan" table="CategoryItem"> <key column="CATEGORY_ID" not-null="true"/> <many-to-many column="ITEM_ID" class="Item"/> </set> </class> <class name="Item" table="ITEM" select-before-update="true"> <id name="id" type="long" column="ITEM_ID">

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 20 of 28 <generator class="increment"/> </id> <version name="version" column="OBJ_VERSION"/> <property name="name" type="string" length="255" not-null="true" update="false" column="ITEM_NAME"/> </class> points to observe: 1. <key> element. the collection table is CategoryItem. key refers to category_id in CategoryItem table and category_id has foreign key relation to the primary key of the category table. 2. <many-to-many> element. This refers to the item_id column in the CategoryItem table and the item_id has foreign key relation to the primary key of the Item table. <many-to-many> tag has attribute class which denotes the association class.

many-to-many bidirectional
<class name="Category" table="CATEGORY"> <id name="id" type="long" column="CATEGORY_ID"> <generator class="increment"/> </id> <version name="version" column="OBJ_VERSION"/> <property name="name" type="string"> <column name="CATEGORY_NAME" not-null="true" length="255"/> </property> <set name="items" cascade="all,delete-orphan" inverse="true" table="CategoryItem"> <key column="CATEGORY_ID" not-null="true"/> <many-to-many column="ITEM_ID" class="Item"/> </set> </class> <class name="Item" table="ITEM" select-before-update="true"> <id name="id" type="long" column="ITEM_ID"> <generator class="increment"/> </id> <set name="categories" cascade="all,delete-orphan" table="CategoryItem"> <key column="ITEM_ID" not-null="true"/> <many-to-many column="CATEGORY_ID" class="Category"/> </set> <version name="version" column="OBJ_VERSION"/> <property name="name" type="string" length="255" not-null="true" update="false" column="ITEM_NAME"/> </class> the principle inverse=true applies for Many-to-Many bidirectional relation also.

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 21 of 28 Each row of the link table is represented by two collection elements, one element at each end of the association. An association between an Item and a Category is represented in memory by the Item instance belonging to the items collection of the Category but also by the Category instance belonging to the categories collection of the Item. The ocde to create the object association also changes. cat.getItems.add(item); item.getCategories().add(category); When you map a bidirectional many-to-many association, you must declare one end of the association using inverse="true" to define which sides state is used to update the link table. We can chose any side as inverse side. inverse="true" setting tells Hibernate to ignore changes made to the categories collection and use the other end of the association (the items collection) as the representation that should be synchronized with the database if we manipulate the association in Java code.

Inheritance mapping Strategies


Table per class hierarchy An entire class hierarchy could be mapped to a single table. This table would include columns for all properties of all classes in the hierarchy. The concrete subclass represented by a particular row is identified by the value of a type discriminator column. discriminator column is a special column to distinguish between persistent classes. This isnt a property of the persistent class; its used internally by Hibernate. Hibernate will automatically set and retrieve the discriminator values. There is one major problem: Columns for properties declared by subclasses must be declared to be nullable. If your subclasses each define several nonnullable properties, the loss of NOT NULL constraints could be a serious problem from the point of view of data integrity. In Hibernate, we use the <subclass> element to indicate a table-per-class hierarchy mapping. Every subclass has its own <subclass> element.

Table per subclass


Another option is to represent inheritance relationships as relational foreign key associations. Every subclass that declares persistent properties has its own table. So, Super class has its own table and properties of superclass are persisted to that table. All the subclasses have separate tables and the instance data of each subclass is inserted into tables (related to subclass). The table for subclass

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 22 of 28 contains columns only for each non-inherited property (each property declared by the subclass itself) along with a primary key that is also a foreign key of the superclass table. Note On primary key: <key> tag is used here. The primary key of the subclass table has a foreign key association to the primary key of the superclass table. The two rows are linked together by their shared primary key value. Later, the subclass instance may be retrieved from the database by joining the subclass table with the superclass table. The primary advantage of this strategy is that the relational model is completely normalized. Schema evolution and integrity constraint definition are straightforward. In Hibernate, we use the <joined-subclass> element to indicate a table-per-subclass mapping. A <joined-subclass> element may contain other <joined-subclass> elements but not a <subclass> element. Hibernate doesnt support mixing of these two mapping strategies. disadvantages: performance may be unacceptable for complex class hierarchies.
Table per concrete class

This strategy uses one table for each (non-abstract) class All properties of a class, including inherited properties, could be mapped to columns of this table, In our example, there are 3 classes. Account and its subclasses SavingAccount and CurrentAccount. In this case, 2 tables are created, one for SavingAccount and one for CurrentAccount. All the instance variables of SavingAccount, including the variables for Account class, are inserted to the SavingAccount table. There is no table for superclass data as in table per subclass strategy. <union-subclass> is used for this strategy. <class name="Payment"> <id name="id" type="long" column="PAYMENT_ID"> <generator class="sequence"/> </id> <property name="amount" column="AMOUNT"/> ... <union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT"> <property name="creditCardType" column="CCTYPE"/> ... </union-subclass> <union-subclass name="CashPayment" table="CASH_PAYMENT"> ... </union-subclass> </class>

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 23 of 28 here 2 tables are involved. one for CreditCardPayment and one for CashPayment.

Hibernate Query Language


HQL is fully object-oriented query language. The Query and Criteria interfaces both define several methods for controlling execution of a query.
The query interfaces

An object-oriented representation of a Hibernate query. A Query instance is obtained by calling Session.createQuery(). The createQuery() method prepares an HQL query: The simplest possible query is from Person , which returns all instances of person. (include package name). Select clause is not mandatory unlike SQL. from person p . p is alias which is common in sql. Query hqlQuery = session.createQuery("from Person"); Multiple classes may appear, resulting in a cartesian product or "cross" join. Query hqlQuery = session.createQuery("from Person, Address"); where clasue The where clause is used to express a restriction in both SQL and HQL; 1. 2. 3. 4. 5. 6. 7. from person p where p.id between 1 and 10. from Person p where p.name in ('sreedhar','krsna') from User u where u.email is null from User u where u.email is not null from Person p where p.name like 'tcube%' where user.firstname like "G%" and user.lastname like "K%" from Person p order by p.name desc

HQL join options


In Hibernate queries, it is not necessary to specify a join condition explicitly. If we specify the name of a mapped Java class association in the query, Hibernate can deduce the table join expression For example, the Person class has an association named addresses with the Address class. from Person p join p.addresses

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 24 of 28 HQL provides four ways of expressing (inner and outer) joins: 1. An ordinary join in the from clause 2. A fetch join in the from clause 3. An implicit association join

The supported join types are borrowed from ANSI SQL inner join left outer join right outer join full join (not usually useful)

ordinary join in the from clause:


In the below example, aliases are used.

from Person p join p.addresses a where p.description like '%abc%' and a.city like Hyd%
In the ordinary join, if there is no select clause, the result would be a Cartesian product. The generated SQL is as follows select person0_.id as id0_0_, addresses1_.addressid as addressid1_1_, person0_.version as version0_0_, person0_.name as name0_0_, addresses1_.version as version1_1_, addresses1_.city as city1_1_, addresses1_.street as street1_1_, addresses1_.personid as personid1_1_ from person person0_ inner join address addresses1_ on person0_.id=addresses1_.personid where addresses1_.city like 'Hyd%' The query returns all combinations of associated Person and Address. But unlike a fetch join, the addresses collection of the Person isnt initialized by the query. Query returns an ordered pair: (Person, Address). In the query result, Hibernate represents an ordered pair as an array.

List<Object[]> list = q.list(); System.out.println("size of list is.."+ list.size()); Iterator<Object[]> itr = list.iterator(); while(itr.hasNext()){ Object[] obj = itr.next(); Person p = (Person)obj[0]; Address a = (Address)obj[1]; System.out.print(p.getName() + " "); System.out.println(a.getCity()); }

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 25 of 28 Instead of a List of Items, this query returns a List of Object[] arrays. At index 0 is the Person, and at index 1 is the Address. A particular Person may appear multiple times, once for each associated Address. Select Clause we dont want the Address in the query result, we can specify a select clause in HQL. This clause is optional in HQl. select clause is mandatory in SQL. We can use the select clause to retrieve only the selected objects:

select p from Person p join p.addresses adrs where p.description like '%abc%' and adrs.city like Hyd% The generated SQL is as follows
select person0_.id as id0_, person0_.version as version0_, person0_.name as name0_ from person person0_ inner join address addresses1_ on person0_.id=addresses1_.personid
The query result contains just Persons, and because its an inner join, only Persons who have address. Query q = session.createQuery("select p from Person p join p.addresses"); List<Person> list = q.list(); Iterator<Person> itr = list.iterator(); while(itr.hasNext()){ Person p = itr.next(); System.out.println(p.getName() + " "); }

fetch join in the from clause


In HQL, you can specify that an association should be eagerly fetched by an outer join using the fetch keyword in the from clause: from Person p left join fetch p.addresses where p.name like '%tcube%' This query returns all Persons with a name that contains the string tcube, and all their addresses, in a single select. When executed, it returns a list of Person instances, with their addresses collection fully initialized. We call this a from clause fetch join. The purpose of a fetch join is performance optimization: We use this syntax only because we want eager initialization of the address collections in a single SQL select.

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 26 of 28 HQL always ignores the mapping document eager fetch (outer join) setting. If youve mapped some associations to be fetched by outer join (by setting outer-join="true" on the association mapping), any HQL query will ignore this preference. You must use an explicit fetch join if you want eager fetching in HQL. HQL will not ignore fetch=subselect in collection mapping.

Implicit Joins
from Address a where a.person.name like '%Foo%' This results in an implicit join on the many-to-one associations from Address to Person the name of this association is item. Hibernate knows that you mapped this association with the person_ID foreign key in the Address table and generates the SQL join condition accordingly. Implicit joins are always directed along many-to-one or one-to-one associations, never through a collection-valued association (you cant write person.addresses.city). the generated sql would be as follows: select address0_.addressid as addressid1_, address0_.version as version1_, address0_.city as city1_, address0_.street as street1_, address0_.personid as personid1_ from address address0_, person person1_ where address0_.personid=person1_.id and person1_.name='john'

Theta Style Joins


the theta-style syntax is useful when your join condition isnt a foreign key relationship mapped to a class association

Using batch fetching


Hibernate can make efficient use of batch fetching, that is, Hibernate can load several uninitialized proxies if one proxy is accessed (or collections). Batch fetching is an optimization of the lazy select fetching strategy. There are two ways you can tune batch fetching: on the class and the collection level. If we enable batch fetching on collections, the behaviour would be as follows. For example, if each Person has a lazy collection of Addresses and 10 persons are currently loaded in the Sesssion, iterating through all persons will generate 10 SELECTs, one for every call to getAddresses(). If you enable batch fetching for the cats collection in the mapping of Person, Hibernate can pre-fetch collections: <class name="Person"> <set name="addresses" batch-size="3"> </set> </class>

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 27 of 28 If we enable batch fetching on class, the behaviour would be as follows. You have 25 Cat instances loaded in a Session, each Cat has a reference to its owner, a Person. The Person class is mapped with a proxy, lazy="true". If you now iterate through all cats and call getOwner() on each, Hibernate will by default execute 25 SELECT statements, to retrieve the proxied owners. You can tune this behaviour by specifying a batch-size in the mapping of Person: <class name="Person" batch-size="10">...</class>

Criteria Query
The simplest criteria query looks like this: session.createCriteria(Item.class); It retrieves all persistent instances of the Item class. This is also called the root entity of the criteria query. The Criteria interface also supports ordering of results with the addOrder() method and the Order criterion: session.createCriteria(User.class) .addOrder( Order.asc("lastname") ) .addOrder( Order.asc("firstname") ); Applying restrictions For a criteria query, you must construct a Criterion object to express a constraint. The Restrictions class provides factory methods for built-in Criterion types. Criterion emailEq = Restrictions.eq("email", "foo@hibernate.org"); Criteria crit = session.createCriteria(User.class); crit.add(emailEq); User user = (User) crit.uniqueResult(); Creating innerjoin Criteria crit = s.createCriteria(Person.class); crit = crit.createCriteria("addresses"); Dynamic Association Fetching List cats = sess.createCriteria(Person.class) .add( Restrictions.like("name", "Fritz%") )

Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 28 of 28 .setFetchMode("addresses", FetchMode.EAGER) .list();

SecondLevel cache
One major advantage of using Hibernate is the caching feature provided by it. A cache keeps a representation of current database state close to the application, either in memory or on disk of the application server machine. The cache is a local copy of the data. The cache sits between your application and the database. Read-only data or mostly read-only can be cached in second level cache. Instead of hitting the database every time, the application looks in the second-level cache for the existence of the data. Application retrieves the data from database only if the data is not present in the secondlevel cache. The cache may be used to avoid a database hit whenever 1. The application performs a lookup by identifier (primary key) 2. The persistence layer resolves an association lazily Good candidate classes for caching are classes that represent Data that changes rarely Non-critical data (for example, content-management data) Data that is local to the application and not shared Bad candidates for second-level caching are Data that is updated often Financial data Data that is shared with a legacy application Enabling the second-level cache involves the following steps. 1) enable it at the global level 2) Chose a cache provider. 3) enable it at the mapping level(hbm.xml) The following cache implementations are built-in in the Hibernate EHCache, OpenSymphony OSCache SwarmCache JBossCache

S-ar putea să vă placă și