Tenemos algunos beans EJB sin estado JavaEE5 que pasan el EntityManager inyectado a sus ayudantes.¿Está bien pasar EntityManagers inyectados a las clases auxiliares de beans de EJB y usarlos?
¿Esto es seguro? Hasta ahora funcionaba bien, pero descubrí un documento de Oracle que indica que su implementación de EntityManager es segura para subprocesos. Ahora me pregunto si la razón por la que no tuvimos problemas hasta ahora, fue solo porque la implementación que estábamos usando resultó ser segura (usamos Oracle).
@Stateless
class SomeBean {
@PersistenceContext
private EntityManager em;
private SomeHelper helper;
@PostConstruct
public void init(){
helper = new SomeHelper(em);
}
@Override
public void business(){
helper.doSomethingWithEm();
}
}
En realidad tiene sentido .. Si EntityManager es thread-insegura, un contenedor tendría que hacer
inercept business()
this.em = newEntityManager();
business();
que no se propagará a sus clases de ayuda.
Si es así, ¿cuál es la mejor práctica en este tipo de situación? ¿Al pasar EntityManagerFactory en lugar de EntityManager?
EDIT: This question es muy interesante por lo que si usted está interesado en esta pregunta, es probable que desee echa un vistazo a éste, también:
EDIT: Más información. Instancias ejb3.0 spec
4.7.11 no reentrante El recipiente debe asegurarse de que sólo uno hilo puede estar ejecutando una instancia en cualquier momento. Si una solicitud de cliente llega para una instancia, mientras que la instancia se ejecutando otra solicitud, el contenedor puede tirar la javax.ejb.ConcurrentAccessException a el segundo cliente [24]. Si se utiliza la vista de cliente EJB 2.1 , el contenedor puede lanzar el java.rmi.RemoteException a la segunda solicitud si el cliente es un cliente remoto , o la javax.ejb.EJBException si el cliente es un local de cliente. [25] Tenga en cuenta que un objeto de sesión está destinado a admitir solo un único cliente. Por lo tanto, sería un error de aplicación si dos clientes intentaron invocar el mismo objeto de sesión . Una implicación de esta regla es que una aplicación no puede realizar llamadas de bucle invertido a una instancia de bean de sesión .
Y,
4.3.2 Inyección de dependencias Un bean de sesión puede utilizar la inyección de dependencias mecanismos para adquirir referencias a recursos u otros objetos en su entorno (ver Capítulo 16, "Enterprise Bean Environment"). Si un grano sesión hace uso de la inyección de dependencias , el contenedor inyecta estas referencias después de la instancia del bean es creado, y antes de cualquier negocio métodos se invocan en el frijol ejemplo.Si se declara una dependencia en el SessionContext, o si la clase de bean implementa la interfaz opcional SessionBean (consulte la Sección 4.3.5), el SessionContext también se inyecta en este momento. Si la inyección de la dependencia falla, la instancia del bean es descartada. Bajo la API EJB 3.0, la clase de bean puede adquirir la interfaz SessionContext a través de la inyección de dependencia sin tener que implementar la interfaz SessionBean. En este caso, la anotación Resource (o el elemento descriptor resource-env-ref deployment ) se usa para denotar la dependencia del bean en el SessionContext. Consulte el Capítulo 16, "Enterprise Bean Environment".
Ahora bien, esto es interesante "La especificación EJB 3.1 dice que la inyección de dependencia solo se realiza en el momento de la construcción, de modo que todos los que llaman de MyRepository usarían la misma instancia de EntityManager". : http: //stackoverflow.com/questions/2015184/how-is-threadsafty-guranteed-with-persistencecontext –
FYI, lea también el § 4.1.13, o vea esta respuesta http: // stackoverflow.com/questions/1954137/how-is-that-instance-pooling-with-ejbs-can-improve-performance/1954229 # 1954229. De modo que se accederá a cada ayudante por un hilo a la vez. – ewernli
Este es exactamente el patrón que estaba pensando en implementar. Estoy muy feliz de ver que es posible. Buena publicación. Gracias. – b3bop