Hibernate Concepts Students (1) Krsna-T-Cube
Hibernate Concepts Students (1) Krsna-T-Cube
Hibernate Concepts Students (1) Krsna-T-Cube
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>
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.
Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 9 of 28
Important Mappings
Krsna T-CUBE Software Consulting private Limited (Teach, Train, Transform) Page 10 of 28
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.
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>
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.
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.
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.
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
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)
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() + " "); }
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'
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", "[email protected]"); 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