Title: Programmation des Applications Internet Internet Application Programming Hibernate These slides and
1Programmation des Applications Internet Internet
Application Programming HibernateThese slides
and case studies can be downloaded from
www.PauWare.com/MTI
2Hibernate
- Hibernate is the most popular persistence
framework in the Java world (NHibernate in the
.NET world) - It is an open source product which can be
downloaded from www.hibernate.org - Hibernate Core is composed of the key libraries
(.jar files) - Hibernate EntityManager is the support for Java
Persistence API (JPA) - Hibernate is the default support for JPA in JBoss
while TopLink is the default in GlassFish - Hibernate eases the development of
database-oriented applications (compared to JDBC
for example) - Hibernate promotes object-orientation
(polymorphism, OO requests through HQL) and
removes the direct non-evolutive codification of
SQL inside the Java code (compared to JDBC)
3Case study (UML model)
4Case study (database schema)
5Case study (persistent object dependencies)
6Hibernate configuration
- The hibernate.cfg.xml file defines the main
properties of the application. It is usually
installed in the Java default package - This file is loaded and interpreted through an
instance of the org.hibernate.cfg.Configuration
class - The key notion behind Hibernate is the notions of
session factory and session - private org.hibernate.SessionFactory
_session_factory new org.hibernate.cfg.Configura
tion().configure().buildSessionFactory() - private org.hibernate.Session getSession()
- return _session_factory.getCurrentSession()
7Example of a hibernate.cfg.xml file
- lt?xml version'1.0' encoding'utf-8'?gt
- lt!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD//EN"
- "http//hibernate.sourceforge.net/hibernate-config
uration-3.0.dtd"gt - lthibernate-configurationgt
- ltsession-factorygt
- ltproperty name"connection.driver_class"gtorg.apach
e.derby.jdbc.ClientDriverlt/propertygt - ltproperty name"connection.url"gtjdbcderby//local
host1527/Prison_de_Nanteslt/propertygt - ltproperty name"connection.username"gtbarbierlt/prop
ertygt - ltproperty name"connection.password"gtlena150496lt/p
ropertygt - ltproperty name"connection.pool_size"gt1lt/propertygt
- ltproperty name"dialect"gtorg.hibernate.dialect.Der
byDialectlt/propertygt - ltproperty name"show_sql"gttruelt/propertygt
- ltmapping resource"com/FranckBarbier/Java/_Prison_
de_Nantes/Detenu.hbm.xml"/gt - ltmapping resource"com/FranckBarbier/Java/_Prison_
de_Nantes/Affaire.hbm.xml"/gt - ltmapping resource"com/FranckBarbier/Java/_Prison_
de_Nantes/Motif.hbm.xml"/gt - ltmapping resource"com/FranckBarbier/Java/_Prison_
de_Nantes/Incarceration.hbm.xml"/gt - ltmapping resource"com/FranckBarbier/Java/_Prison_
de_Nantes/Decision.hbm.xml"/gt - lt/session-factorygt
8The notion of session
- Sessions are spaces in which objects get
Hibernate-oriented states - An object is included in a session as follows
- getSession().persist(_detenu)
- When attached (Persistent state), an object is
synchronized with the database. All modifications
on this object will lead to appropriate
modifications in the database - When flushed (or closed), all objects in a
session lose their Persistent state to recover a
Transient state. - Sessions are manually or automatically associated
with database transactions
9Session-oriented actions
- find (or get, or load) -gt it leads to the
Persistent state and to a SELECT statement, for
example - return (Detenu) session.load(Detenu.class,
primary_key) - persist (or save) -gt it leads to an INSERT
statement at flush/commit time - merge (or update) -gt it leads to an UPDATE
statement - evict -gt it leads to the Detached state
- delete -gt it leads to a DELETE statement
- refresh -gt it leads to a SELECT statement
10Persistent objects
- A Hibernate persistent object (a.k.a. Plain Old
Java Object or POJO) is a Java class whose
instances are supposed to persist in a database - A POJO is ruled by constraints constructor
without arguments, normalized getter and setter
methods for persistent attributes, no use of the
final Java modifier for classes, methods and
attributes - A POJO implements the java.io.Serializable Java
interface - A class playing the role of primary composite key
must also be subject to the above constraints
11Persistent object lifecycle
- Note the Transient state is realized through the
value of the unsaved-value attribute
12Configuring persistent objects
- The mapping between database elements (tables)
and persistent objects are described in XML
files, for instance Detenu.hbm.xml - Persistent fields are associated with table
columns, for instance - lt?xml version"1.0" encoding"UTF-8"?gt
- lt!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http//hibernate.sourceforge.net/hibernate-mappin
g-3.0.dtd"gt - lthibernate-mappinggt
- ltclass name"com.FranckBarbier.Java._Prison_de_Nan
tes.Detenu" table"DETENU"gt -
- ltproperty column"PRENOM" name"_prenom"
type"string"/gt - ltproperty column"NOM" name"_nom"
type"string"/gt - ltproperty column"DATE_NAISSANCE"
name"_date_naissance" type"date"/gt - ltproperty column"LIEU_NAISSANCE"
name"_lieu_naissance" type"string"/gt -
13Mapping several tables in a persistent object
- Example incorporating the DETENU and
INCARCERATION tables into the Detenu POJO - ltjoin optional"false" table"INCARCERATION"gt
- ltkey column"N_ECROU"/gt
- ltproperty column"DATE_INCARCERATION"
name"_date_incarceration" type"date"/gt - lt/joingt
- The mark optional"true" is based on the fact
that one may have "missing" rows in the
INCARCERATION table
14Setting up business identifiers
- Hibernate does not support so well business
primary keys. However, one may have - lthibernate-mappinggt
- ltclass name"com.FranckBarbier.Java._Prison_de_Nan
tes.Detenu" table"DETENU"gt - ltid column"N_ECROU" name"_n_ecrou"gt
- ltgenerator class"assigned"/gt
- lt/idgt
15Overriding equals and hashCode
- public class Detenu implements java.io.Serializabl
e - private String _n_ecrou
- public String get_n_ecrou()
- return _n_ecrou
-
- public void set_n_ecrou(String n_ecrou)
- _n_ecrou n_ecrou
-
- // other persistent fields here
- _at_Override
- public boolean equals(Object object)
- if (!(object instanceof Detenu))
- return false
-
- Detenu other (Detenu) object
- if (_n_ecrou ! other._n_ecrou (_n_ecrou
null !_n_ecrou.equals(other._n_ecrou))) - return false
-
- return true
16Setting up composite identifiers
- Hibernate does not also support so well composite
(business) primary keys, for instance - lthibernate-mappinggt
- ltclass name"com.FranckBarbier.Java._Prison_de_Nan
tes.Affaire" table"AFFAIRE"gt - ltcomposite-id class"com.FranckBarbier.Java._Priso
n_de_Nantes.AffairePK" name"_primary_key"gt - ltkey-property column"N_AFFAIRE"
name"_n_affaire" type"string"/gt - ltkey-property column"NOM_JURIDICTION"
name"_nom_juridiction" type"string"/gt - lt/composite-idgt
-
- As shown here, composite primary keys require
dedicated classes, e.g., AffairePK
17Setting up technical (surrogate) identifiers
- Example
- lthibernate-mappinggt
- ltclass name"com.FranckBarbier.Java._Prison_de_Nan
tes.Detenu" table"DETENU"gt - ltid column"ID_DETENU" name"_id_detenu"gt
- ltgenerator class"native"/gt
- lt/idgt
18DBMS-oriented identifier generation
- Example
- lthibernate-mappinggt
- ltclass name"com.FranckBarbier.Java._Prison_de_Nan
tes.Detenu" table"DETENU"gt - ltid column"ID_DETENU" name"_id_detenu"gt
- ltgenerator class"sequence"gt
- ltparam name"sequence"gtmy_generatorlt/paramgt
- lt/generatorgt
- lt/idgt
-
- Creating sequences in Oracle CREATE SEQUENCE
my_generator
19Other modes for managing identifiers
- Example
- ltid column"ID_DETENU" name"_id_detenu"
type"Long" unsaved-value"null"gt - ltgenerator class"increment"/gt
- lt/idgt
- Note the unsaved-value attribute is set to
undefined when identifiers are assigned by users
(business primary keys) - Other modes uuid.hex or uuid.string (uses IP
addresses to compute identifiers), foreign
20One-to-one associations
- An incarceration is concerned with one and only
one prisoner (and vice-versa) - ltone-to-one name"_detenu" constrained"false"/gt
- constrained"true" is used when there is a
foreign key between the two tables - The foreign key of the Incarceration persistent
object may be constrained by that of the Detenu
persistent object - ltid column"N_ECROU" name"_n_ecrou"gt
- ltgenerator class"foreign"gt
- ltparam name"property"gt_detenult/paramgt
- lt/generatorgt
- lt/idgt
21Many-to-many associations
- Example (Detenu.hbm.xml file)
- ltbag name"_toutes" table"DETENU_AFFAIRE"gt
- ltkey column"N_ECROU"/gt
- ltmany-to-many class"com.FranckBarbier.Java._Priso
n_de_Nantes.Affaire"gt - ltcolumn name"N_AFFAIRE"/gt
- ltcolumn name"NOM_JURIDICTION"/gt
- lt/many-to-manygt
- lt/baggt
- An extract from the Detenu class is as follows
- private java.util.CollectionltAffairegt _toutes
- public java.util.CollectionltAffairegt get_toutes()
- return _toutes
-
- public void set_toutes(java.util.CollectionltAffair
egt toutes) - _toutes toutes
22Bidirectionality
- Example (Affaire.hbm.xml file)
- ltset inverse"true" name"_participants"
table"DETENU_AFFAIRE"gt - ltkeygt
- ltcolumn name"N_AFFAIRE"/gt
- ltcolumn name"NOM_JURIDICTION"/gt
- lt/keygt
- ltmany-to-many class"com.FranckBarbier.Java._Priso
n_de_Nantes.Detenu" column"N_ECROU"/gt - lt/setgt
- An extract from the Affaire class is as follows
- private java.util.CollectionltDetenugt
_participants - public java.util.CollectionltDetenugt
get_participants() - return _participants
-
- public void set_participants(java.util.Collectionlt
Detenugt participants) - _participants participants
23Bidirectionality consistency
- The inverse"true" mark in Affaire.hbm.xml forces
Hibernate to maintain the DETENU_AFFAIRE table
from the Detenu persistent object - As a result, the following code is required
(Affaire class) - public void addTo_participants(Detenu detenu)
- get_participants().add(detenu)
- detenu.get_toutes().add(this)
-
- public void removeFrom_participants(Detenu
detenu) - get_participants().remove(detenu)
- detenu.get_toutes().remove(this)
-
24One-to-many associations
- Example (Detenu.hbm.xml file)
- ltlist name"_condamnation" table"CONDAMNATION"
lazy"false"gt - ltkey column"N_ECROU"/gt
- ltlist-index column"N_TYPE_DECISION"/gt
- ltone-to-many class"com.FranckBarbier.Java._Prison
_de_Nantes.Condamnation"/gt - lt/listgt
- An extract from the Detenu class is as follows
- private java.util.CollectionltCondamnationgt
_condamnation - public java.util.CollectionltCondamnationgt
get_condamnation() - return _condamnation
-
- public void set_condamnation(java.util.Collectionlt
Condamnationgt condamnation) - _condamnation condamnation
25Many-to-one associations
- Example (Incarceration.hbm.xml file)
- ltmany-to-one column"N_MOTIF" name"_motif"
not-null"true"/gt - ltmany-to-one name"_principale" not-null"true"gt
- ltcolumn name"N_AFFAIRE"/gt
- ltcolumn name"NOM_JURIDICTION"/gt
- lt/many-to-onegt
- The not-null"true" mark forces Hibernate to
respect the 1.. multiplicity compared to the
0.. multiplicity
26Lazy loading (1/2)
- Given a persistent object, a question is about
the access to its linked (also persistent)
objects. For instance, given d an instance of
Detenu, one may want to access to its criminal
cases - java.util.CollectionltAffairegt all
d.get_toutes() - An extract of the mapping file is as follows
- ltset name"_toutes" table"DETENU_AFFAIRE"
lazy"true" fetch"select"gt lt!--default values--gt - ltkey column"N_ECROU"/gt
- ltmany-to-many class"com.FranckBarbier.Java._Priso
n_de_Nantes.Affaire"gt - ltcolumn name"N_AFFAIRE"/gt
- ltcolumn name"NOM_JURIDICTION"/gt
- lt/many-to-manygt
- lt/setgt
27Lazy loading (2/2)
- By default, dependent objects are not loaded
(when an object is itself loaded, d below) and
thus becomes persistent. As a result, Hibernate
executes a deferred SELECT request when one
accesses the criminal cases of a prisoner - java.util.CollectionltAffairegt all
d.get_toutes() - The way by which lazy loading may be inhibited,
relies on the lazy and/or fetch parameter as
follows - ltset name"_toutes" table"DETENU_AFFAIRE"
lazy"false" - ltkey column"N_ECROU"/gt
- ltmany-to-many class"com.FranckBarbier.Java._Priso
n_de_Nantes.Affaire"gt - ltcolumn name"N_AFFAIRE"/gt
- ltcolumn name"NOM_JURIDICTION"/gt
- lt/many-to-manygt
- lt/setgt
- Note fetch"join" (left outer join) prevails on
lazy
28Cascading actions
- Insertions, deletions may be cascaded from a
persistent object to its dependent objects - ltbag name"_decision" table"DECISION"
cascade"all"gt - ltkey column"N_ECROU"/gt
- ltone-to-many class"com.FranckBarbier.Java._Prison
_de_Nantes.Decision"/gt - lt/baggt
- Values save-update, persist, merge, delete, lock,
evict and replicate are for one-to-one,
many-to-one tags (outside collections) - Values for collections are save-update, persist,
merge, delete, delete-orphan, lock, evict,
replicate and all-delete-orphan
29Inheritance
- Hibernate supports three main modes for managing
inheritance relationships (and thus
polymorphism) - A column in the table corresponding to the root
class plays the role of discriminator. There are
no tables for the subclasses - Subclasses have corresponding tables and a
foreign key on their ancestor table - No need of a table exists for the root class
30Inheritance, no tables for subclasses
- Example (Decision.hbm.xml)
- ltdiscriminator column"N_TYPE_DECISION"
type"string" insert"false"/gt - ltsubclass name"com.FranckBarbier.Java._Prison_de_
Nantes.Condamnation" discriminator-value"1"gt - ltproperty name"_duree" column"DUREE"
type"integer"/gt - lt/subclassgt
- ltsubclass name"com.FranckBarbier.Java._Prison_de_
Nantes.Reduction_peine" discriminator-value"2"gt - ltproperty name"_duree" column"DUREE"
type"integer"/gt - lt/subclassgt
- ltsubclass name"com.FranckBarbier.Java._Prison_de_
Nantes.Liberation_definitive" discriminator-value
"3"gt - ltproperty name"_date_liberation" column
"DATE_LIBERATION" type"date"/gt - lt/subclassgt
- Disadvantages some data in the DECISION table
are with null values for specialized attributes,
e.g., _duree
31Inheritance, tables for all classes
- ltjoined-subclass name"com.FranckBarbier.Java._Pri
son_de_Nantes.Condamnation" table"CONDAMNATION"gt - ltkeygt
- ltcolumn name"N_TYPE_DECISION"/gt
- ltcolumn name"N_ECROU"/gt
- ltcolumn name"DATE_DECISION"/gt
- lt/keygt
- ltproperty name"_duree" column"DUREE"
type"integer"/gt - lt/joined-subclassgt
- ltjoined-subclass name"com.FranckBarbier.Java._Pri
son_de_Nantes.Reduction_peine" table"Reduction_pe
ine"gt - ltkeygt
- ltcolumn name"N_TYPE_DECISION"/gt
- ltcolumn name"N_ECROU"/gt
- ltcolumn name"DATE_DECISION"/gt
- lt/keygt
- ltproperty name"_duree" column"DUREE"
type"integer"/gt - lt/joined-subclassgt
- ltjoined-subclass name"com.FranckBarbier.Java._Pri
son_de_Nantes.Liberation_definitive"
table"Liberation_definitive"gt - ltkeygt
- ltcolumn name"N_TYPE_DECISION"/gt
32No table need for the root class
- ltunion-subclass name"com.FranckBarbier.Java._Pris
on_de_Nantes.Condamnation" table"CONDAMNATION"gt - ltproperty column"DUREE" name"_duree"
type"integer"/gt - lt/union-subclassgt
- ltunion-subclass name"com.FranckBarbier.Java._Pris
on_de_Nantes.Reduction_peine" table"REDUCTION_PEI
NE"gt - ltproperty column"DUREE" name"_duree"
type"integer"/gt - lt/union-subclassgt
- ltunion-subclass name"com.FranckBarbier.Java._Pris
on_de_Nantes.Liberation_definitive"
table"LIBERATION_DEFINITIVE"gt - ltproperty column"DATE_LIBERATION"
name"_date_liberation" type"date"/gt - lt/union-subclassgt
33Sessions and transactions
- Hibernate supports a home-made transaction
management mode - org.hibernate.Session session
_session_factory.openSession() - org.hibernate.Transaction utx
session.beginTransaction() -
- utx.commit() // or utx.rollback()
- JTA-oriented transactions
- private javax.transaction.UserTransaction _utx
-
- org.hibernate.Session session
session_factory.getCurrentSession() - _utx.begin()
-
- _utx.commit() // or _utx.rollback()
34Working with JTA
- ltproperty name"hibernate.transaction.manager_look
up_class"gtorg.hibernate.transaction.SunONETransact
ionManagerLookuplt/propertygt lt!--GlassFish
support--gt - ltproperty name"hibernate.transaction.factory_clas
s"gtorg.hibernate.transaction.JTATransactionFactory
lt/propertygt - ltproperty name"hibernate.current_session_context_
class"gtjtalt/propertygt