Showing posts with label flushing. Show all posts
Showing posts with label flushing. Show all posts

Wednesday, October 25, 2017

Hibernate EntityManager Important Concepts

Entity States in a Persistence Context

transient

the entity has been initiated but is not associated with a persistence context, typically not identifier has been assigned

managed/persistent

the entity has an associated identifier and is associated with a persistence context

detached

the entity has an associated identifier but is not associated with a persistence context

removed

the entity has an associated identifier and is associated with a persistence context, however it is scheduled for removal from the database.

Flushing

When the flush() of an EntityManager is called, it synchronizes the state of the persistence context with the underlying database.

By default, Hibernate uses the AUTO flush mode, a flush is  triggered automatically when:
  • prior to committing a Transaction
  • prior to executing a JPQL/HQL query that overlaps with the queued entity actions (inserts, updates, deletes etc.)
  • before executing any native SQL query that has not registered synchronization

Flushing Operation Order

The order in which SQL statements are executed is given by the ActionQueue and not by the order in which entity state operations have been previously defined. 

The ActionQueue executes all operations in the following order:

  1. OrphanRemovalAction
  2. EntityInsertAction or EntityIdentityInsertAction
  3. EntityUpdateAction
  4. CollectionRemoveAction
  5. CollectionUpdateAction
  6. CollectionRecreateAction
  7. EntityDeleteAction

Caching

HibernateSessionacts as a transaction-level cache of persistent data. Once an entity becomes managed, that object is added to the internal cache of the current persistence context (EntityManager or Session). The persistence context is also called the first-level cache, and it’s enabled by default.
Hibernate provides integration with various caching providers for the purpose of caching data outside the context of a particular Session.  It is called the second-level cache.

EntityManager Operations

entityManager.persist( person ); //if FlushModeType is commit, then wait till a flush to save data to database
entityManager.remove( person );
entityManager.getReference( Person.class, personId ); // Not loaded yet
entityManager.find( Person.class, personId );
entityManager.flush();
entityManager.refresh( person );
entityManager.merge( person );
entityManager.contains( person );
entityManager.detach( person );
entityManager.clear()

CascadeType

ALL

cascades all entity state transitions

PERSIST

cascades the entity persist operation.

MERGE

cascades the entity merge operation.

REMOVE

cascades the entity remove operation.

REFRESH

cascades the entity refresh operation.

DETACH

cascades the entity detach operation.

Transactional Patterns

session-per-operation

commit after each database call

session-per-request

session-per-conversation

Automatic Versioning
Hibernate can perform automatic optimistic concurrency control for you. It can automatically detect (at the end of the conversation) if a concurrent modification occurred during user think time.
Detached Objects
If you decide to use the session-per-request pattern, all loaded instances will be in the detached state during user think time. Hibernate allows you to reattach the objects and persist the modifications. The pattern is called session-per-request-with-detached-objects. Automatic versioning is used to isolate concurrent modifications.
Extended Session
(session.disconnect())
The Hibernate Session can be disconnected from the underlying JDBC connection after the database transaction has been committed and reconnected when a new client request occurs. This pattern is known as session-per-conversation and makes even reattachment unnecessary. Automatic versioning is used to isolate concurrent modifications and the Session will not be allowed to flush automatically, only explicitly.

Session-per-application (anti-pattern)

The Hibernate Session, like the JPA EntityManager, is not a thread-safe object and it is intended to be confined to a single thread at once.