@ ApplicationScoped CDI bean i @PersistenceContext - czy to bezpieczne ?

Czy można zrobić coś takiego z CDI?

@Named
@ApplicationScoped
public class DAO {

   @PersistenceContext
   private EntityManager entityManager;

}

Rozumiem, że EntityManager samo w sobie nie jest bezpieczne dla wątków i dlatego nie powinno być używane we wspólnym globalnym kontekście, takim jak @ApplicationScoped. Jednakże, ponieważ obiekt iniekcyjny {[3] } jest w rzeczywistości owijarką świadom wątku wokół bazowego EntityManager, Czy to sprawia, że jest to w porządku?

Widziałem inne posty na ten temat, ale nie byłem w stanie znaleźć wiarygodnej odpowiedzi na ten konkretny przypadek. Na przykład:

Java CDI @PersistenceContext and thread safety

Wygląda na to, że jest bezpieczny w użyciu z @Stateless, na przykład - ale nie jestem pewien, czy to ze względu na sposób działania @Stateless, czy z powodu czegoś wewnętrznego do @PersistenceContext.

EDIT Źródłem mojego zamieszania jest to, że opakowanie @PersistenceContext injected EntityManager zdaje się być świadome bieżącego wątku, aby dowiedzieć się, czy jest już transakcja w toku. Więc może jestem mylenie nić-świadomość z nić-Bezpieczeństwo i są to dwie różne rzeczy.

Author: Martijn Pieters, 2012-12-15

1 answers

Jestem prawie pewien, że w tym przypadku CDI nie tworzy kontekstowego proxy dla menedżera jednostek. W końcu, w jakim zakresie to będzie? Możesz chcieć czegoś podobnego do hipotetycznego @ThreadScoped lub po prostu @RequestScoped, ale @PersistenceContext nie jest adnotacją CDI i CDI nie modyfikuje swojej semantyki.

Więc to, co się tutaj dzieje, to wstrzyknięcie "managed bean" platformy Java EE 6, które jest podobne do wstrzykiwania menedżera entity w Servlet. Oba przypadki dają wystąpienie, które nie jest bezpieczne w użyciu bezpośrednio.

Wygląda na to, że jest bezpiecznie używać z @Stateless, na przykład - ale nie jestem pewien, czy to ze względu na sposób działania @Stateless, czy z powodu czegoś nieodłącznego do @PersistenceContext.

To ze względu na sposób działania. Każde żądanie (wywołanie) metody w bezstanowej bean jest kierowane przez kontener do unikalnej instancji. Pojemnik gwarantuje, że żadne dwa wątki nie są aktywne w tej samej fasoli.

Z CDI można uzyskać podobnie jak w przypadku żądania poprzez umieszczenie menedżera encji w zakresie żądania i wstrzyknięcie go do zakresu aplikacji:

import javax.enterprise.context.RequestScoped;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@RequestScoped
public class EntityManagerProvider {

    @PersistenceContext
    private EntityManager entityManager;

    public EntityManager getEntityManager() {
        return entityManager;
    }

}

Inject this into the bean where you previously injected the entity manager:

@Named
@ApplicationScoped
public class DAO {

   @Inject
   private EntityManagerProvider entityManagerProvider;

}

To da ci unikalnego menedżera jednostek na żądanie. Możesz łatwo przekształcić to również w metodę producer, więc nie będziesz musiał dzwonić getEntityManager() do wstrzykniętego dostawcy.

 24
Author: Arjan Tijms,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-15 14:47:31