Sunday, May 10, 2015

Persisting objects with Hibernate.
Hibernate defines three object states. Transient, persistent and detached
Transient state is for example a new object. It has no ID associated and consequently no representation in the database. These objects will be collected by the garbage collector. The session helper methods can be used to save the object.
A persistent state is one where there is a database representation available. When we load an object we put it in this state. This object is now in the scope of session. Any changes made to the object will be detected.
A detached state is one where the object goes out of scope of session. Changes can be made because the reference is valid. When the object is reattached to a session,  it and all  it's changes can become persistent again. This enables a way to work with long running unit if work which are called application transaction.
The save method on the session makes an object persistent. It does not guarantee to return an identifier. The assignment might happen at flush time.
The load method of a Session provides a way of retrieving a persistent instance based on its identifier.
Load can work through a proxy. If the class is mapped with a proxy, load returns an initialized proxy which does not actually hit the database. This helps with creating associations or working with batches. If the load has to reach a database and there is no matching row, then there is an unrecoverable exception.Its better to detect the database record with a get method which returns null if there's none. Objects can be loaded for update only when there's a LockMode specified or a cascade style specified.
Reload of an object can work with refresh in the sequence save()->flush()->refresh()
Objects saved by the session are all transactional persistent instances and any changes to the persistent state will be persisted when the session is flushed. Therefore there is no need to call a method such as update between load and flush.
Hibernate works with states only. It does not work with SQL statements from users. That approach might be better with JDBC. Further Batch processing conflicts with online transaction processing, so prefer not to do batching with Hibernate although some options are available.
When an object is loaded but presented to a higher layer where it may spend an inordinate amount of time may require separate transactions for the retrieving and saving. These "long" unit of work therefore have to work with versioned data.
To reattach this detached instance, we call update if the session does not already contain a  persistent instance. We use merge when we want to merge the modifications at any time without consideration of the state of the session.

If there are associated items to the entity we want to save, then they too can be persisted in any order as long as there is no not null constraints on a foreign key column. There is never a risk of violating a foreign key constraint. On the other hand there is risk of violating a not Null foreign constraint if the order is not maintained.

As an aside, the lock method can be used to reassociate a detached object. However the detached instance has to be unmodified. There are several LockMode available.

We now look at automatic state detection. This is enabled via saveOrUpdate method.
This method is supposed to generate a new identifier or reattach with an existing identifier. But first let's note that update, merge and saveOrUpdate methods are not to be called if we are using the same session. They are typically used when going from older session to a newer session.

SaveOrUpdate uses object versioning either with a version or a timestamp. If the version is the same, save it. If the version is different update it

Merge is very different. If there is a persistent entity with the same identifier in the session,  merge will  update it. If there is no persistent entity, merge will load from the database or create a new one. The returned entity doesn't become part of the session but remains detached.

#codingexercise


GetAllNumberRangeProductNinthRootPowerTen(Double [] A)



{





if (A == null) return 0;





Return A.AllNumberRangeProductNinthRootPowerTen();


}



No comments:

Post a Comment