Saturday, May 25, 2013 1:14

Hibernate Study Note

Tagged with:
Posted by on Monday, January 5, 2009, 13:16
This news item was posted in Documentum category and has 0 Comments so far.

This is my study note about hibernate, which is written around two years ago.

Hibernate
===========================================================

Books:
Java Persistence with Hibernate

Database Manipulation
———————————————————–
Process of retrieveing objects
* Search in the Session Cache.
* Search in the “NonExists” record
* Search in the sessionFactory Cache if it could.
* Select SQL, (add the infomation in the “NonExists” record if object not exsist, and return null.)
* Use the ResultSet to get the obejct.
* Bring the object to Session Cache.
* Excute the Inteceptor.onLoad().
* Bring the object to Session Factory Cache.
* Excute the onLoad() if obejct has implemented the LifeCycle interface.
* Return the object.

get() and load()
* if the object not exsist, Null will be returned by get(), and ObjectNotFoundException by load().
* load() could return a proxy class and use the sessionFactory cache.

find() and iterate()
* Hibernate 2 ‘s Query and Criteria are based on these two methods, Session.find() equals Session.createQuery.list(), Session.iterate() equals Session.createQuery.iterate() in version 3.

save(), update() and saveOrUpdate()

list()
uniqueResult()

Priciple
———————————————————–
Instance states
* transient (has no persistent identity)
* persistent (has a persistent identity and, perhaps, a corresponding row in the database,guarantees that persistent identity is equivalent to Java identity)
* detached (has a persistent identity and, perhaps, a corresponding row in the database, no guarantees about the relationship between persistent identity and Java identity)
* switch

|——————————— END (garbage collection)———————————
| save(), saveOrUpdate() close(), evict(), clear() |
@—new()–> transient <===========================> persistent <==============================> detached—
| delete() | update(), saveOrUpdate()
| get(), load(), find(), iterator(), list()… |
|——————————————————–
* Judge states of transientg and detached
- id unsaved-value
- version
- if Interceptor.isUnsaved return True
* PO(persistence object) vs VO (value object)
Judge: if managed by Entity Map
Extends: VO as a DTO(Data Transfer Object)
Usage: Apache Jakarta Commons Beanutils to copy properties. (throws IllegalAccessExcpetion)

Object identify and equality
* compare with memory address (“==”)
* compare with infomation (equals() and hashCode())
we have to override the equals() nad hashCode() methods if we intend to put instansts of persistence classes in a Set and
intend to use reattchement of detatched instances.

Dirty Data Checking(Two ways)
– 1. Checking the data object (Check the setter methods by Dynamic Proxy Pattern or CGLIB)
– 2. Compare with data version (Adopted by Hibernate)
public void commit() throws HibernateException(){
……
if( session.getFlushMode()!= FlushMode.NEVER) session.flush(); //flushEverything();
……
}
Attribution of EntityEntry — loadedState.

Data Cache Strategy
* Transaction level Cache
* Application/Process level Cache
* Cluster level cache
* Cache in Hibernate:
- use the identifier to load data. (Session.load(), Session.iterate())
- Lazy-init
- Session Level (Session.evict, Session.clear)
- SessionFactory Level (support a simple Hashtable [org.hibernate.cache.HashtableCacheProvider],
third party cache: JCS, EHCache, OSCache, JBoss Cache, SwarmCache)

Transactions and Concurrency
* ACID (Atomic, Consistency, Isolation, Durability)
* Based on JDBC
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
……
tx.commit();

Connection conn = getConnection();
conn.setAutoCommit(false); // AutoCommit has been set to false when openSession(), so if no transaction, the save() method will not
// affect the db(support tranaction)
……
conn.commit();

* Based on JTA (Java Transaction API,UserTransaction, TransactionManager, Transaction)
JTA can span many connections or sessions.
Session.beginTransaction have call the IntitialContext.lookup()
Easy to use JTA in EJB, because there is no need to call transaction manager in the code.

Concurrency
Locking
* Pessimistic Locking (use the “for update” statement)
String hqlStr = “from Student as stu where stu.name = ‘lidnux’”
Query query = session.createQuery(hqlStr);
query.setLockMode(“stu”, LockMode.UPGRADE);
query.list();
* LockMode
//
LockMode.NONE
LockMode.WRITE
LockMode.READ

LockMode.UPGRATE
LockMode.UPGRATE_NOWAIT

* Set the LockMode
Criteria.setLockMode
Query.setLockMode
Session.lock

* Optimistic Locking

Relationship
———————————————————–
id
* Generator
increment/identify/sequence/hilo/seqhilo/uuid/guid/native/assigned/select/foreign/sequence-identify
One-to-One association (two varieties)
– 1. primary key association (A special Hibernate identifier generation strategy called foreign)
* Add mappings
<one-to-one name=”certificate” class=”lidnux.model.certificate” fetch=”join” cascade=”all”/>
<one-to-one name=”student” class=”lidnux.model.student” constrainted=”true”/>
one-to-one association has no column element, we can specify it in id element.
* Use identifier generation
<id>
<generator>
<param name=”peroperty”>student</param>
</generator>
</id>
* Use in code
student.setCertificate(certificate);
cerfificate.setStudent(student); //requeried
StudentDAO.save(student); //cascade save

– 2. unique foreign key association (many-to-one association with unique element to make bidirectional association)
* Add mappings
<one-to-one name=”certificate” class=”lidnux.model.certificate” fetch=”join” cascade=”all” />
<many-to-one name=”student” class=”lidnux.model.student” unique=”true” column=”student_id” />

Many-to-Many association

Query
———————————————————–
Criteria Query
* Narrowing the result set
List students = session.createCriteria()
.add( Restrictions.like(“name”, “lidnux%”))
.add( Restrictions.between(“weight”, minWeight, maxWeight))
.list();
Built-in criterion types;
To specify SQL directly:
// {alias} placeholder with be replaced by the row alias of the queried entity.
.add( Restrictions.sqlRestriction(“lower({alias}.name) like lower(?)”, “Lidnux%”, Hibernate.STRING) )
To get a criterion from a Property instance
Property age = Property.forName(“age”);
List students = session.createCriteria(Student.class)
.add( Restrictions.disjunction()
.add( age.isNull() )
.add( age.eq( new Integer(0) ) )
.add( age.eq( new Integer(1) ) )
.add( age.eq( new Integer(2) ) )
) )
.add( Property.forName(“name”).in( new String[] { “Lidnux”, “Lidanux”, “Dan” } ) )
.list();
* Ordering the results
.addOrder( Order.asc(“name”) )
.addOrder( Order.desc(“age”) )
.setMaxResults(50)
.list();

.add( Property.forName(“name”).like(“F%”) )
.addOrder( Property.forName(“name”).asc() )
.addOrder( Property.forName(“age”).desc() )
.setMaxResults(50)
.list();

* Associations
List teams = sess.createCriteria(Team.class)
.add( Restrictions.like(“name”, “03242%”) )
.createCriteria(“students”) //return a new instance of Criteria,which refers to the elements of the student collection.
.add( Restrictions.like(“name”, “lidnux%”))
.list();

In certain circumstances, this method is useful
List teams = session.createCriteria(Team.class)
.createAlias(“students”, stu)
.add(Restrictions.like(stu.name,”lidnux%”)
.list();

Session.get/load的区别:
1.如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObejctNotFoundException。
2.Load方法可返回实体的代理类类型,而get方法永远直接返回实体类。
3.Load方法可以充分利用内部缓存和二级缓存中现有数据,而get方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据,将越过二级缓存,直接调用SQL完成数据读取。
hibernate-study-note.txt

No Responses to “Hibernate Study Note”

Leave a Reply

You can leave a response, or trackback from your own site.