Post on 10-Sep-2018
transcript
EJB – JPA Integration
Persistence Contexts
Concepts: Connection Pool, Data Source, Persistence Unit Connection pool – DB connection store:
making a new connection is expensive, therefor some number of connections are being created during the startup of a system and stored within a pool
connection pool specifies: DBMS host/port, DB name, minimum/maximum number of
connections, etc.
Data Source is a pair: {name, connectionPool} thus connection pool can be retrieved by its name
JPA Persistence Unit specifies data source and optional list of database tables is defined in persistence.xml file
EJB - JPA integration 2
persistence.xml example<persistence version="2.1" ...>
<persistence-unit name="StudentsPU" transaction-type="JTA">
<jta-data-source>
java:comp/jdbc/StudentsDataSource
</jta-data-source>
</persistence-unit>
</persistence>
EJB - JPA integration 3
Concepts: Persistence Context and EntityManager Persistence Context – cache of Entity objects
Each EntityManager instance has its own single non-shared Persistence Context: one-to-one relationship
Official definition (JPA 2.1 specification chapter 7.1):
A persistence context is a set of managed entity instances in which for any persistent entity identity there is a unique entity instance. Within the persistence context, the entity instances and their lifecycle are managed by the entity manager.
EntityManager – API to work with Persistence Context
to put entities to cache and to remove them from cache
EJB - JPA integration 4
Entity’s life-cycle (managed via EntityManager API)
EJB - JPA integration 5
While entity is in this state, changes are synchronized with DB automatically
!!!
Persistence Context (cache) contains only
managed entities
!!!
Entity’s life-cycle: states new – The entity instance was created in memory, but
not yet in the database Changes to the entity are not synchronized with the
database – entity is not yet managed
managed – The entity has a persistent identity in the database and is synchronized with the database Changes to the entity will be synchronized with the
database automatically
detached – The entity does have a persistent identity but is not synchronized with the database
removed – The entity is deleted from the database
EJB - JPA integration 6
Automatic synchronization with DB While an entity is in managed state its persistent fields are
automatically synchronized with database Most often synchronization happens just before transaction
commit Changes in database (performed by some other application)
are not brought back to entity – database is not being monitored for changes
Sometimes we want the synchronization to happen in the middle of the transaction for example: we made some changes and we want these
changes to be visible in the query that is executed later in this transaction
flush() forces to performe the synchronization at once
EJB - JPA integration 7
Manual synchronization refresh(entity) – data from database are
overwritten over entity’s data (at the end of transaction)
entity2 = merge(entity1): if entity1 is managed
data of entity1 is written to DB (at the end of transaction) entity1 is returned as result
if entity1 is not managed (is detached) entity1 is cloned the clone is made managed (entity1 remains detached!) clone’s data is written to DB (at the end of transaction) clone is returned as the result of merge() operation
EJB - JPA integration 8
Entity Life-cycle: summary While entity is in managed state its data is
automatically synchronized with database
least worries for a programmer
Managed state may be lost in two ways:
by asking to delete the entity from database by calling method remove()
when Persistence Context (cache) is destroyed (in the picture: "Persistence context ends")
This can be done manually by calling: EntityManager.close()
EJB - JPA integration 9
Problems for Programmer EntityManager is not thread-safe
Different threads must use different EntityManagers
EntityManagers must not only be created but also closed too Otherwise free memory will end soon, since entities
loaded by EntityManager are being cached
Summary – JPA gives only unmanaged Persistence Contexts, programmers must themselves: manage threads
create and close EntityManager instances
manage memory
EJB - JPA integration 10
Solution: Managed Persistence Contexts EJB container is the actual manager, taking care of:
Managing threads
Creating/closing EntityManager instances automatically
EJB - JPA integration 11
Managed Persistence Context Types Persistence Context (PC) Type is cache life-cycle
specification Specifies when the cache (Persistence Context) is created and
when is closed
EJB specification defines two PC types: transactional PC – life-cycle is scoped by a single transaction
@PersistenceContext(type=PersistenceContextType.TRANSACTION)
extended PC – life-cycle is scoped by the life-cycle of a stateful session bean instance @PersistenceContext(
type=PersistenceContextType.EXTENDED)
if type is not specified, type is transactional by default
EJB - JPA integration 12
@Statelesspublic class Bank {
@PersistenceContext private EntityManager em;
public Account createAccount(String ownerName) {Account account = new Account();account.ownerName = ownerName;em.persist(account);return account;
}public Account readAccount(int accKey) {Account account = em.find(Account.class, accKey);return account;
}public Account updateAccount(Account account) {account = em.merge(account);return account;
}public void deleteAccount(Account account) {em.remove(em.merge(account));
}}
Example 1
EJB - JPA integration 13
Example 1
EJB - JPA integration 14
@Statelesspublic class Bean {
// this is transactional PersistenceContext:@PersistenceContext private EntityManager em;
public void method1() {1. Transaction begins2. EntityManager is created as soon as one of its methods is
called (but not sooner)2. EntityManager is used to work with entities ...3. Leaving the method, the transaction ends. Just before
transaction commit, all the changes are sent to database and EntityManager is closed. All its entities become detached.}
Changes, made to entities between calls to the methods above, are not synchronized with database (entities are detached!) If we want to save changes to database, we have to call EntityManager.merge() method.
EJB - JPA integration 15
Notes for example 1
@Statefulpublic class Bank {
@PersistenceContext(type=EXTENDED)private EntityManager manager;
public Account createAccount(String ownerName) {Account account = new Account();account.ownerName = ownerName;manager.persist(account);return account;
}public Account readAccount(int accKey) {Account account = manager.find(Account.class, accKey);return account;
}public void update() {// automatic managed entity synchronization is performed // just before transaction commit.
}public void deleteAccount(Account account) {manager.remove(account);
}}
EJB - JPA integration 16
Example 2
Example 2
EJB - JPA integration 17
@Statefulpublic class Bank {
@PersistenceContext(type=PersistenceContextType.EXTENDED) private EntityManager manager;
// EntityManager is created when session bean is created,// and is closed when session bean is destroyed
public void method1() {1. Transaction begins2. EntityManager is used to work with entities ...3. Leaving the method, the transaction ends. Just before
transaction commit, all the changes are sent to database, EntityManager remains alive. All entities remain managed.}
public void method2() {The same
}
// changes, made to entities in between calls to method1 and method2, are written to database at the end of transaction!
Notes for example 2
EJB - JPA integration 18
Persistence Context Type Comparison Transactional PC consumes less memory (cache is
always destroyed at the end of transaction (i.e. request))
Extended PC allows web tier to navigate entity relationships
PC (cache) is alive, EntityManager "sees" all the operations performed with an entity, loads related entities transparently on demand
EJB - JPA integration 19
EJB component types and Persistence Context types Transactional Persistence Context may be used with:
stateless session beans
stateful session beans
singleton session beans
Extended Persistence Context may be used with:
stateful session beans only
EJB - JPA integration 20
Practical problem – component decomposition
If business logic is complex, we want to split it to several EJB components
client calls the first component that calls another one and so on
Imagine, that all components need to work with database, so all of them contain:@PersistenceContext EntityManager em;
there will be problems if all em fields contain different EntityManagers
Example: the first component loads list of entities, passes it to the second component, the second one tries to delete those entities from DB
remove() method called in the second component would throwexception because entities loaded by the first EntityManager are not in the second EntityManager's cache (Persistence Context)
EJB - JPA integration 21
Other limitations From JPA 2.0 specification:
It is the responsibility of the application to insure that an instance is managed in only a single persistence context.
The behavior is undefined if the same Java instance is made managed in more than one persistence context
An entity manager must not be shared among multiple concurrently executing threads, as the entity manager and persistence context are not required to be threadsafe.
Entity managers must only be accessed in a single-threaded manner
So, one global EntityManager instance used by all components is not a solution!
EJB - JPA integration 22
Possible solutions The first component in a use case (use case controller)
passes its EntityManager to all other components as a parameter
every method must have additional parameter of type EntityManager – cumbersome
EJB specification introduced EntityManager “lending”mechanism instead:
1. persistence context inheritance
2. persistence context propagation
EJB - JPA integration 23
1. Persistence context propagation (JPA spec. section 7.6.4.1) The persistence context is propagated across the entity
manager instances as the transaction is propagated. If a EJB component is called and there is no
transaction or the transaction is not propagated, the persistence context is not propagated.
If a component is called and the transaction is propagated into that component: If the component is a stateful session bean to which an
extended persistence context has been bound and there is a different persistence context bound to the transaction, an EJBException is thrown by the container.
Otherwise, if there is a persistence context bound to the transaction, that persistence context is propagated and used.
EJB - JPA integration 24
Client Comp1
Comp2 Comp5
Comp3 Comp4 Comp6
R
R
R RN
RN
R
R – RequiredRN – RequiresNew
Transaction and Persistence Context
Transaction and Persistence Context
Persistence Context Propagation
EJB - JPA integration 25
2. Extended persistence context inheritance (JPA spec. 7.6.3.1) If a stateful session bean instantiates a stateful
session bean (executing in the same EJB container instance) which also has such an extended persistence context (since Java EE 7: with the same synchronization type), the extended persistence context of the first stateful session bean is
inherited by the second stateful session bean and bound to it, and this rule recursively applies—independently of whether
transactions are active or not at the point of the creation of the stateful session beans.
If the stateful session beans differ in declared synchronization type, the EJBException is thrown by the container.
If the persistence context has been inherited by any stateful session beans, the container does not close the persistence context until all such stateful session beans have been removed or otherwise destroyed.
EJB - JPA integration 26
Generalization of rules 1 and 2 Let k1 and k2 be EJB component instances, k1 injects k2
(with the help of @EJB or @Inject)
If both components have declared @PersistenceContext:
Transactional → Transactional , propagates
Transactional → Extended , error
Extended → Transactional , propagates
Extended →newExtended , inherits
Extended →old Extended , error
k2 was born before k1 and already has its own EntityManager object
EJB - JPA integration 27
Generalization of rules 1 and 2 Important: if transaction does not propagate,
persistence context does not propagate too
Transaction will never propagate to component using RequiredNew transactional attribute
This is actually OK: different transactions must work with different entity caches
EJB - JPA integration 28
Java EE 7 (JPA 2.1): Persistence Context Synchronization Type By default, a container-managed persistence context is of
type SynchronizationType.SYNCHRONIZED. Such a persistence context is automatically joined to the
current JTA transaction.
A persistence context of type UNSYNCHRONIZED is not enlisted in any JTA transaction unless explicitly joined to that transaction by the invocation
of the EntityManager joinTransaction() method.
When a JTA transaction exists, a persistence context of type UNSYNCHRONIZED is propagated with that transaction according to the rules in section 7.6.4.1 regardless of whether the persistence context has been joined to that transaction.
EJB - JPA integration 29
Java EE 7: Synchronized and Unsynchronized PC Let k1 and k2 be EJB component instances, k1 injects k2
(with the help of @EJB or @Inject)
If both components have declared @PersistenceContext: Unsynchronized → Unsynchronized , propagates
Synchronized → Synchronized , propagates
Synchronized → Unsynchronized , propagates
Unsynchronized → Synchronized , error
EJB - JPA integration 30
Summary EJB and JPA are well integrated
automatic transactions, automatic cache life-cycle management, persistence context (cache) propagation
Without EJB things would be much more difficult: manual transactions
manual EntityManager creation and closing
EntityManagers would have to be passed as parameters to other components implementing the same use-case
manual thread management: programmer would have to ensure that two threads are not using the same EntityManager
EJB - JPA integration 31
Summary We get all this for free just by writing these lines:
@Stateless // or @Stateful, @Singletonpublic class MyComponent {
@PersistenceContextprivate EntityManager em;
...}
EJB - JPA integration 32
What is important for an architectPresentation Tier
ViewTemplate language
Expression language
Drag-and-drop
Preview in browser
ControllerDeclarative page flow
Declarative form validation
Page composition
Form resubmition prevention
Inversion of Control (IoC)
Dependency Injection
Action-based controller
Component-oriented
controller
Request, session contexts
Conversation context
Business Logic Tier
Stateful components
Stateless components
Memory management
(pooling)
Distribution transparency
Declarative transactions
Declarative security
Declarative persistency
Data TierObject/Relational Mapping (ORM)
CRUD SQL generation
Many-to-many relationships
Primary key generation
Lazy resolution of queries
n+1 select problem
Inheritance/polymorphic queries
Query caching
Disconnected operation mode
...
RDBMS vendor independence
EJB - JPA integration 33