JPA használata Java SE alkalmazásban (CDI-vel) – III. rész

Posted by | · · · | Egy csésze kávé · Szoftverfejlesztés | Nincs hozzászólás a(z) JPA használata Java SE alkalmazásban (CDI-vel) – III. rész bejegyzéshez

Az előző bejegyzést azzal fejeztem be, hogy az EntityManager producer metódusunk minden injection point-hoz egy új EntityManager-t példányosít, amely meggátolja a @Transactional annotációnk használatát. A mostani bejegyzésben ezen problémára szeretnék megoldást adni.

 

Olyan CDI producer metódust kell készítenünk, amely szálanként egy EntityManager példányt szolgáltat. Ebben segítségünkre lesz a ThreadLocal osztály.

 

Lehet felmerült benned a következő kérdés: “Miért nem csak egy EntityManager példány alkalmazás szinten?”
Azért nem, mert az EntityManager példányok nem szál biztosak.

Szálanként egy EntityManager példány

Az EntityManager páldányosításáért felelős osztály az EntityManagerProducer. Az osztály ApplicationScoped, annak érdekében, hogy csak egy példány létezzen belőle alkalmazás szinte. A weld container sikeres indulását a ContainerInitialized eseményben jelzi, erre az eseményre feliratkozva példányosíthatjuk az EntityManagerFactory-t.
A producer metódusban a ThreadLocal példány segítségével megvalósítjuk, hogy szálanként mindig egy EntityManager példányt készítsünk.

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.jboss.weld.environment.se.events.ContainerInitialized;

@ApplicationScoped
public class EntityManagerProducer {

    private EntityManagerFactory emf;

    private static final ThreadLocal<EntityManager> ENTITY_MANAGER_STORE = new ThreadLocal<>();

    public void init(@Observes ContainerInitialized containerInitialized) {
        emf = Persistence.createEntityManagerFactory("default");
    }

    @Produces
    public EntityManager getEntityManager() {
        EntityManager em = ENTITY_MANAGER_STORE.get();
        if (em == null) {
            em = emf.createEntityManager();
            ENTITY_MANAGER_STORE.set(em);
        }
        return em;
    }

    public void closeEntityManager(@Disposes EntityManager entityManager) {
        ENTITY_MANAGER_STORE.remove();
        if (entityManager.isOpen()) {
            entityManager.close();
        }
    }
}

Összefoglaló

Készítettem egy példa alkalmazást, amelyben egyben és működő formában láthatjuk az eddig bemutatottakat.

 

A példa alkalmazás egy egyszerű címjegyzék, amelyben személyek nevét és e-mail címét rögzíthetjük.

Screenshot from 2016-02-20 11:32:22

A felület Java FX 8-al készült.
A forráskód elérhető github-on: Address book

Share on FacebookShare on Google+Email this to someoneTweet about this on TwitterShare on RedditShare on LinkedIn

No Comments

Leave a comment