tutorial setrollbackonly messagedrivencontext mdb ejemplo driven bean java-ee transactions weblogic

java ee - setrollbackonly - @Singleton bean no se pudo inicializar debido a un estado de transacción no esperado



queue jms java (2)

Tenía un escenario en el que necesitaba que se cargara un bean (ReportManager) al inicio de la aplicación, por lo que puede programar informes para su ejecución (sondeados desde la base de datos por el bean DataStore).

Buscando en Google encontré las anotaciones @Singleton, @Startup y @DependsOn, que he usado así:

@Singleton @Startup @DependsOn("DataStore") public class ReportManager { @EJB DataStore dataStore; @PostConstruct public void scheduleReports() { logger.log("INITIALIZED"); List<Report> reports = dataStore.getReports(); .... } } @Singleton @RolesAllowed("user") //I had security checks implemented like that beforehand public class DataStore { @PostConstruct public void initialize() { logger.log("INITIALIZED"); } public List<Report> getReports() { ... } }

El problema fue que estaba obteniendo una excepción realmente extraña durante el tiempo de implementación:

<2012-09-27 14:04:15 CEST> <Warning> <Deployer> <BEA-149004> <Failures were detected while initiating deploy task for application "app".> <2012-09-27 14:04:15 CEST> <Warning> <Deployer> <BEA-149078> <Stack trace for message 149004 weblogic.application.ModuleException: Exception starting module: EJBModule(app-ejb-1.0-SNAPSHOT.jar) Unable to deploy EJB: ReportManager from app-ejb-1.0-SNAPSHOT.jar: Singleton ReportManager(Application: app, EJBComponent: app-ejb-1.0-SNAPSHOT.jar) failed to initialize. at weblogic.ejb.container.deployer.EJBModule.start(EJBModule.java:592) ..... Caused By: weblogic.ejb.container.InternalException: Transaction marked rollback or not expected transaction status: 1 at weblogic.ejb.container.manager.SingletonSessionManager.postCallback(SingletonSessionManager.java:464)

No es realmente un mensaje de excepción completo. Especialmente porque tampoco recibía entradas de registro "INICIALIZADAS". Cuando comenté la invocación de dataStore.getReports (), todo funcionaba bien y los beans se construyeron en el orden correcto (se produjeron mensajes "INICIALIZADOS"). La inclusión de la invocación del método dataStore estaba causando el error anterior y de alguna manera estaba suprimiendo todo el resultado del registro.

Estoy usando Weblogic 12c.


En mi caso, estoy usando la clase SpringLoader.java, que es un @Singleton que carga la configuración de Spring. Spring está configurado con un programador de Quartz que está intentando acceder a su (s) tabla (s) DB (como parte de alguna transacción).

Entonces, en mi caso, ayudó a agregar la siguiente línea a esta clase de SpringLoader: @TransactionManagement (TransactionManagementType.BEAN)

Después de eso, se muestra un mensaje de error más significativo: ORA-00942: tabla o vista no existe.

Por cierto: también valía la pena agregar esta línea: @ConcurrencyManagement (ConcurrencyManagementType.BEAN)


Finalmente, descubrí qué causaba el error. Era la declaración @RolesAllowed que estaba bloqueando la invocación del método debido al contexto de seguridad vacío, no se estableció en el método @PostConstruct cuando se ejecutó en @Startup bean (de la especificación EJB 3.1, capítulo 4.3.4 : los métodos del interceptor de devolución de llamada del ciclo de vida PostConstruct ejecutan un contexto de seguridad no especificado).

Lo que se necesitaba para hacerlo funcionar era simplemente agregar @PermitAll al método invocado:

@PermitAll public List<Report> getReports() { ... }

El error fue tan erróneo que decidí poner este caso aquí, ya que no pude buscar la respuesta en Google.