14 - EJB and JPA Integration

Embed Size (px)

Citation preview

  • 7/25/2019 14 - EJB and JPA Integration

    1/33

    EJB JPA Integration

    Persistence Contexts

  • 7/25/2019 14 - EJB and JPA Integration

    2/33

    Concepts: Connection Pool, Data

    Source, Persistence Unit Connection pool DB connection store:

    making a new connection is expensive, therefor some numberof 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 ofconnections, etc.

    Data Source is a pair: {name, connectionPool}

    thus connection pool can be retrieved by its name Persistence Unit specifies data source and optional list of

    database tables is defined in persistence.xml file

    EJB - JPA integration 2

  • 7/25/2019 14 - EJB and JPA Integration

    3/33

    persistence.xml example

    studentuDBDataSource

    EJB - JPA integration 3

  • 7/25/2019 14 - EJB and JPA Integration

    4/33

    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 inwhich for any persistent entity identity there is a unique entityinstance. Within the persistence context, the entity instances

    and their lifecycle are managed by the entity manager. EntityManager API to work with Persistence Context

    to manage the cache programmatically

    EJB - JPA integration 4

  • 7/25/2019 14 - EJB and JPA Integration

    5/33

    Entitys life-cycle (managed via

    EntityManager API)

    EJB - JPA integration 5

    While entity is in thisstate, changes aresynchronized with

    DB automatically

    !!!

    Persistence Context(cache) contains only

    managed entities

    !!!

  • 7/25/2019 14 - EJB and JPA Integration

    6/33

    Entitys 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 synchronizedwith the database Changes to the entity will be synchronized with the

    database automatically detached The entity does have a persistent identity

    but is not synchronizedwith the database

    removed The entity is deleted from the database

    EJB - JPA integration 6

  • 7/25/2019 14 - EJB and JPA Integration

    7/33

    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 beingmonitored for changes

    Sometimes we want the synchronization to happen in themiddle 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 thistransaction

    flush() forces to performe the synchronization at once

    EJB - JPA integration 7

  • 7/25/2019 14 - EJB and JPA Integration

    8/33

    Manual synchronization refresh(entity) data from database are

    overwritten over entitys data (at the end oftransaction)

    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!) clones data is written to DB (at the end of transaction) clone is returned as the result of merge() operation

    EJB - JPA integration 8

  • 7/25/2019 14 - EJB and JPA Integration

    9/33

    Entity Life-cycle: summaryWhile 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 callingmethod remove()

    when Persistence Context (cache) is destroyed (in thepicture: "Persistence context ends")

    This can be done manually by calling:EntityManager.close()

    EJB - JPA integration 9

  • 7/25/2019 14 - EJB and JPA Integration

    10/33

    Problems for Programmer EntityManager is not thread-safe

    Different threads must use different EntityManagers

    EntityManagers must not only be created but alsoclosed 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

  • 7/25/2019 14 - EJB and JPA Integration

    11/33

    Solution: Managed Persistence

    Contexts EJB container is the actual manager, taking care of:

    Managing threads

    Creating/closing EntityManager instances automatically

    EJB - JPA integration 11

  • 7/25/2019 14 - EJB and JPA Integration

    12/33

    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 statefulsession bean instance @PersistenceContext(

    type=PersistenceContextType.EXTENDED)

    if type is not specified, type is transactional by default

    EJB - JPA integration 12

    @St t l

  • 7/25/2019 14 - EJB and JPA Integration

    13/33

    @Stateless

    public 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

  • 7/25/2019 14 - EJB and JPA Integration

    14/33

    Example 1

    EJB - JPA integration 14

    Stateless

  • 7/25/2019 14 - EJB and JPA Integration

    15/33

    Statelesspublic class Bean {

    // this is transactional PersistenceContext:

    @PersistenceContext private EntityManager em;

    public void method1() {1. Transaction begins

    2. EntityManager is created as soon as one of its methods iscalled (but not sooner)

    2. EntityManager is used to work with entities ...

    3. Leaving the method, the transaction ends. Just beforetransaction commit, all the changes are sent to database andEntityManager 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 callEntityManager.merge() method.

    EJB - JPA integration 15

    Notes for example 1

    @Stateful

  • 7/25/2019 14 - EJB and JPA Integration

    16/33

    @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

  • 7/25/2019 14 - EJB and JPA Integration

    17/33

    Example 2

    EJB - JPA integration 17

    @Stateful

  • 7/25/2019 14 - EJB and JPA Integration

    18/33

    @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 begins

    2. EntityManager is used to work with entities ...

    3. Leaving the method, the transaction ends. Just beforetransaction 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 andmethod2, are written to database at the end of transaction!

    Notes for example 2

    EJB - JPA integration 18

  • 7/25/2019 14 - EJB and JPA Integration

    19/33

    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 entityrelationships

    PC (cache) is alive, EntityManager "sees" all theoperations performed with an entity, loads relatedentities transparently on demand

    EJB - JPA integration 19

  • 7/25/2019 14 - EJB and JPA Integration

    20/33

    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

    P ti l bl t

  • 7/25/2019 14 - EJB and JPA Integration

    21/33

    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 allof 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 thoseentities from DB

    remove() method called in the second component would throwexception because entities loaded by the first EntityManager arenot in the second EntityManager's cache (Persistence Context)

    EJB - JPA integration 21

  • 7/25/2019 14 - EJB and JPA Integration

    22/33

    Other limitations From JPA 2.0 specification:

    It is the responsibility of the application to insure that aninstance is managed in only a single persistence context.

    The behavior is undefined if the same Java instance is mademanaged in more than one persistence context

    An entity manager must not be shared among multipleconcurrently executing threads, as the entity manager andpersistence 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 allcomponents is not a solution!

    EJB - JPA integration 22

  • 7/25/2019 14 - EJB and JPA Integration

    23/33

    Possible solutions The first component in a use case (use case controller)

    passes its EntityManager to all other components as aparameter

    every method must have additional parameter of typeEntityManager cumbersome

    EJB specification introduced EntityManager lendingmechanism instead:

    1. persistence context inheritance

    2. persistence contextpropagation

    EJB - JPA integration 23

  • 7/25/2019 14 - EJB and JPA Integration

    24/33

    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, thepersistence context is not propagated.

    If a component is called and the transaction is propagatedinto 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, anEJBException is thrown by the container.

    Otherwise, if there is a persistence context bound to thetransaction, that persistence context is propagated and used.

    EJB - JPA integration 24

  • 7/25/2019 14 - EJB and JPA Integration

    25/33

    Client Comp1

    Comp2 Comp5

    Comp3 Comp4 Comp6

    R

    R

    R RN

    RN

    R

    R RequiredRN RequiresNew

    Transaction and

    Persistence Context

    Persistence Context Propagation

    EJB - JPA integration 25

  • 7/25/2019 14 - EJB and JPA Integration

    26/33

    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 JavaEE 7: with the same synchronization type),

    the extended persistence context of the first stateful session bean isinherited by the second stateful session bean and bound to it, and this rule recursively appliesindependently of whether

    transactions are active or not at the point of the creation of thestateful 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 persistencecontext until all such stateful session beans have been removedor otherwise destroyed.

    EJB - JPA integration 26

  • 7/25/2019 14 - EJB and JPA Integration

    27/33

    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

    ExtendednewExtended , inherits

    Extendedold Extended , error k2was born before k1 and already has its own EntityManager object

    EJB - JPA integration 27

  • 7/25/2019 14 - EJB and JPA Integration

    28/33

    Generalization of rules 1 and 2 Important: if transaction does not propagate,

    persistence context does not propagate too

    Transaction will never propagate to component usingRequiredNew transactional attribute

    This is actually OK: different transactions must work withdifferent entity caches

    EJB - JPA integration 28

  • 7/25/2019 14 - EJB and JPA Integration

    29/33

    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 notenlisted 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 typeUNSYNCHRONIZED is propagated with that transactionaccording to the rules in section 7.6.4.1 regardless of

    whether the persistence context has been joined to thattransaction.

    EJB - JPA integration 29

  • 7/25/2019 14 - EJB and JPA Integration

    30/33

    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

    SynchronizedUnsynchronized , propagates

    Unsynchronized Synchronized , error

    EJB - JPA integration 30

  • 7/25/2019 14 - EJB and JPA Integration

    31/33

    Summary EJB and JPA are well integrated

    automatic transactions, automatic cache life-cyclemanagement, 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 sameEntityManager

    EJB - JPA integration 31

  • 7/25/2019 14 - EJB and JPA Integration

    32/33

    SummaryWe get all this for free just by writing these lines:

    @Stateless // or @Stateful,@Singleton

    public class MyComponent {

    @PersistenceContext

    private EntityManager em;

    ...

    }

    EJB - JPA integration 32

  • 7/25/2019 14 - EJB and JPA Integration

    33/33

    What is important for an architect

    Presentation TierView

    Template 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 InjectionAction-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 queriesn+1 select problem

    Inheritance/polymorphic queries

    Query caching

    Disconnected operation mode

    ...

    RDBMS vendor independence

    i i 33