Mais conteúdo relacionado
Semelhante a 04 dataaccess (20)
Mais de thirumuru2012 (7)
04 dataaccess
- 1. Professional Open Source™
Data Access with Hibernate
Persistent objects and persistence contexts
© JBoss, Inc. 2003, 2004. 07/17/04 1
- 2. Object state transitions and Session methods
Professional Open Source™
new
Transient
garbage
save()
saveOrUpdate() delete()
get()
load()
find()
iterate()
etc. Persistent
evict() update()
close()* saveOrUpdate()
clear()* lock()
garbage
Detached
* affects all instances in a Session
© JBoss, Inc. 2003, 2004. 2
- 3. Transient objects
Professional Open Source™
Transient instances
– instances of a persistent class instantiated with the new operator
– transient, they have no persistent state
– garbage collected if dereferenced by the application
– have no database identity
Transient instances may be made persistent by
– calling Session.save(object)
– creating a reference from another instance that is already persistent
© JBoss, Inc. 2003, 2004. 3
- 4. Persistent objects
Professional Open Source™
Persistent instances
– have database identity
– Include any instance retrieved with a query, lookup by identifier or
navigation
– are managed, changes are automatically flushed to the database
– are transactional, changes can be rolled back in the database only
– Persistent instances are always associated with a persistence context.
Persistent instances may be made transient by
– calling Session.delete(object)
– “orphan delete” (later)
© JBoss, Inc. 2003, 2004. 4
- 5. Removed State
Professional Open Source™
An object is in the removed state if it has been scheduled for deletion
at the end of a unit of work, but it’s still managed by the persistence
context until the unit of work completes.
A removed object shouldn’t be reused because it will be deleted from
the database as soon as the unit of work completes.
© JBoss, Inc. 2003, 2004. 5
- 6. Detached objects
Professional Open Source™
Detached instances
– are instances with database identity that are not associated with any open
Session
– are no longer managed by Hibernate
– represent database state, that is potentially stale
Persistent instances become detached by
– calling Session.evict(object)
– clearing the Session
– closing the Session
Detached instances become persistent by
– calling Session.lock(object, lockMode)
– calling Session.update(object, lockMode)
– creating a reference from another instance that is already persistent
© JBoss, Inc. 2003, 2004. 6
- 7. The persistence context
Professional Open Source™
Persistence Context :
– Persistence context can be considered to be a cache of managed entity
instances.
– Session has an internal persistence context
– All entities in persistent state and managed in a unit of work are cached
in this context.
Use of Persistence context :
– Hibernate can do automatic dirty checking and transactional write-
behind.
– Hibernate can use the persistence context as a first-level cache.
– Hibernate can guarantee a scope of Java object identity.
– Hibernate can extend the persistence context to span a whole
conversation.
© JBoss, Inc. 2003, 2004. 7
- 8. Automatic dirty checking
Professional Open Source™
– Persistent instances are managed in a persistence context—their
state is synchronized with the database at the end of the unit of
work. When a unit of work completes, state held in memory is
propagated to the database by the execution of SQL INSERT,
UPDATE, and DELETE statements (DML).
– Hibernate may synchronize with the database before execution of
a query. This ensures that queries are aware of changes made
earlier during the unit of work.
– Hibernate doesn’t update the database row of every single
persistent object in memory at the end of the unit of work. ORM
software must have a strategy for detecting which persistent
objects have been modified by the application. We call this
automatic dirty checking. An object with modifications that have
not yet been propagated to the database is considered dirty.
© JBoss, Inc. 2003, 2004. 8
- 9. Transparent transaction-level write-behind
Professional Open Source™
– With transparent transaction-level write-behind, Hibernate
propagates state changes to the database as late as possible but
hides this detail from the application.
– By executing DML as late as possible (toward the end of the
database transaction), Hibernate tries to keep lock-times in the
database as short as possible.
© JBoss, Inc. 2003, 2004. 9
- 10. About update queries
Professional Open Source™
– Hibernate is able to detect exactly which properties have been
modified so that it’s possible to include only the columns that need
updating in the SQL UPDATE statement.
– By default, Hibernate includes all columns of a mapped table in
the SQL UPDATE statement (hence, Hibernate can generate this
basic SQL at startup, not at runtime).
– If you want to update only modified columns, you can enable
dynamic SQL generation by setting dynamic-update="true" in a
class mapping
© JBoss, Inc. 2003, 2004. 10
- 11. Persistence Context cache
Professional Open Source™
A persistence context is a cache of persistent entity instances. This
means it remembers all persistent entity instances you’ve handled in
a particular unit of work.
Automatic dirty checking is one of the benefits of this caching.
Another benefit is repeatable read for entities and the performance
advantage of a unit of work-scoped cache.
© JBoss, Inc. 2003, 2004. 11
- 12. The scope of object identity
Professional Open Source™
It is extremely important to understand the differences between
– Java object identity: a == b
– Database identity: a.getId().equals(b.getId()
The conditions when both are equivalent
is called the scope of object identity!
Hibernate implements session-scoped identity – the two notions of
identity are equivalent for instances associated with a particular
session.
© JBoss, Inc. 2003, 2004. 12
- 13. The Hibernate identity scope
Professional Open Source™
Session session1 = sf.openSession();
Transaction tx1 = session.beginTransaction();
Object a = session1.load(Category.class, new Long(1234) );
Object b = session1.load(Category.class, new Long(1234) );
if ( a == b )
System.out.println("a and b are identicial and the same database
identity.");
tx1.commit();
session1.close();
Session session2 = sf.openSession();
Transaction tx2 = session.beginTransaction();
Object b2 = session2.load(Category.class, new Long(1234) );
if ( a != b2 )
System.out.println("a and b2 are not identical.");
tx2.commit();
session2.close();
© JBoss, Inc. 2003, 2004. 13
- 14. Outside of the identity scope
Professional Open Source™
In an instance becomes detached,
it leaves the scope of object identity.
So, if we use detached instances in our application, we should not
use == to test for identity. What should we use instead?
© JBoss, Inc. 2003, 2004. 14
- 15. Identity and equality contracts
Professional Open Source™
Do we have to implement equals()and hashCode()?
– the default implementation uses Java object identity
– no good for detached objects
– especially not if we put them in collections:
Session session1 = sf.openSession();
Transaction tx1 = session.beginTransaction();
Object itemA = session1.load(Item.class, new Long(1234) );
tx1.commit();
session1.close();
Session session2 = sf.openSession();
Transaction tx2 = session.beginTransaction();
Object itemB = session2.load(Item.class, new Long(1234) );
tx2.commit();
session2.close();
Set allObjects = new HashSet();
allObjects.add(itemA);
allObjects.add(itemB);
System.out.println(allObjects.size()); // How many elements? 2
© JBoss, Inc. 2003, 2004. 15
- 16. Implementing equals() and hashCode()
Professional Open Source™
Could we compare identifiers?
– for entities with surrogate keys, it is uninitialized for transient instances
– identity of the instance changes when it becomes persistent, contrary to
the contract of java.util.Set (the hashcode changes)
Could we compare all properties except for the surrogate key?
– identity of the instance changes when we modify the object, contrary to
the contract of java.util.Set (the hashcode changes)
– could potentially cause initialization of a whole graph of associated
objects, just to evaluate equals()
– two instances with the same database identity might not be equal!
– Can two instances with different database identity be equal?
We need a business key.
© JBoss, Inc. 2003, 2004. 16
- 17. Using business keys for equality
Professional Open Source™
A business key is a property or a combination of properties that is
– unique for each instance with the same database identity
– unique, constant and not null only for the comparison time span
public class Item {
public boolean equals(Object other) {
if (this == other) return true;
if (!(other instanceof Item)) return false;
final Item item = (Item) other;
if (!getSummary().equals(item.getSummary())) return false;
if (!getCreated().equals(item.getCreated())) return false;
return true;
}
public int hashCode() {
int result;
result = getSummary().hashCode();
return 29 * result + getCreated().hashCode();
}
}
© JBoss, Inc. 2003, 2004. 17
- 18. Extending a persistence context
Professional Open Source™
A particular conversation reuses the same persistence context for all
interactions.
All request processing during a conversation is managed by the same
persistence context. The persistence context isn’t closed after a
request from the user has been processed. It’s disconnected from the
database and held in this state during user think-time. When the user
continues in the conversation, the persistence context is reconnected
to the database, and the next request can be processed.
At the end of the conversation, the persistence context is
synchronized with the database and closed.
This eliminates the detached state .
Also eliminates the need for manual reattachment or
merging of object state between contexts .
Will see how to use extended persistent context later …….
© JBoss, Inc. 2003, 2004. 18
- 19. The Hibernate Session
Professional Open Source™
The Hibernate Session is the persistence manager interface for
– basic CRUD (create, read, update, delete) operations (Session)
– query execution (Session, Query, Criteria)
– control of transactions (Transaction)
– management of the transaction-level cache
At the beginning of a unit-of-work, the application thread
– looks up the SessionFactory
– obtains a Session
A SessionFactory is expensive to create, a Session is not!
In fact, a Session only obtains a JDBC connection when needed.
© JBoss, Inc. 2003, 2004. 19
- 20. Making an object persistent
Professional Open Source™
User user = new User();
user.getName().setFirstName("John");
user.getName().setLastName("Doe");
Session session = sessions.openSession();
Transaction tx = session.beginTransaction();
session.save(user);
tx.commit();
session.close();
Hibernate executes SQL only as neccessary, in this case,
when the Transaction is committed. Hibernate uses
a transaction-scope write-behind strategy.
© JBoss, Inc. 2003, 2004. 20
- 21. Updating a detached instance
Professional Open Source™
user.setPassword("secret");
Session sessionTwo = sessions.openSession();
Transaction tx =
sessionTwo.beginTransaction();
sessionTwo.update(user);
user.setLoginName("jonny");
tx.commit();
sessionTwo.close();
The call to update() attaches the detached instance with the new
Session, it doesn't matter if it's modified before or after the
update(). Hibernate always treats the object as dirty and schedules
an SQL UPDATE., which will be executed during flush. One way to
avoid this UDPATE statement is to configure the class mapping of
Item with the select-before-update="true“ attribute. Hibernate then
determines whether the object is dirty by executing a SELECT
statement and comparing the object’s current state to the current
database state.
© JBoss, Inc. 2003, 2004. 21
- 22. Locking a detached instance
Professional Open Source™
Session sessionTwo = sessions.openSession();
Transaction tx =
sessionTwo.beginTransaction();
sessionTwo.lock(user, LockMode.NONE);
user.setPassword("secret");
user.setLoginName("jonny");
tx.commit();
sessionTwo.close();
Changes made before the call to lock() are not synchronized with
the database. In this example, we don't even perform a version check
(LockMode.NONE), only reattach the object.
© JBoss, Inc. 2003, 2004. 22
- 23. Retrieving objects
Professional Open Source™
Session session = sessions.openSession();
Transaction tx = session.beginTransaction();
int userID = 1234;
User user = session.get(User.class, new
Long(userID));
// "user" might be null if it doesn't exist
User user = session.load(User.class, new
Long(userID));
// will create only proxy . Will throw an
Exception //if row is not found in db when the proxy
is initialized
tx.commit();
session.close();
Objects looked up by their identifier value are associated with a
Session and automatically dirty-checked inside a Session.
© JBoss, Inc. 2003, 2004. 23
- 24. Making a persistent object transient
Professional Open Source™
Session session = sessions.openSession();
Transaction tx = session.beginTransaction();
int userID = 1234;
User user = session.get(User.class, new
Long(userID));
session.delete(user);
tx.commit();
session.close();
Deleted objects are transient after the Session is closed and will be
garbage collected if they are no longer referenced by other objects .
But for that transient object, id will be the same. Hibernate can also
roll back the identifier of any entity that has been deleted, if you
enable the hibernate.use_identifier_rollback configuration option
© JBoss, Inc. 2003, 2004. 24
- 25. Making a detached object transient
Professional Open Source™
Session session = sessions.openSession();
Transaction tx = session.beginTransaction();
session.delete(user);
tx.commit();
session.close();
Detached objects can be directly reattached and
scheduled for deletion in a single call.
© JBoss, Inc. 2003, 2004. 25
- 26. Merging the state of a detached object
Professional Open Source™
If the reattachment through update() clashes with this already
persistent instance, a NonUniqueObjectException
is thrown.
solution is to merge the two items
© JBoss, Inc. 2003, 2004. 26