Nuxeo CoreSession and Transactions - easysoa/EasySOA GitHub Wiki
See also Nuxeo's more recent post about the topic.
- Through an event listener's context
- Through a Seam context
- Through a Restlet context
- By opening a repository manually
- Via an "UnrestrictedSessionRunner"
- Through the WebEngine context
- In tests: by dependency injection
Any document event holds an event context which is a DocumentEventContext instance. It is then ensured to contain a CoreSession (not always the case with other event contexts). Example:
public class ServiceAPIListener implements EventListener { public void handleEvent(Event event) { EventContext ctx = event.getContext(); if (!(ctx instanceof DocumentEventContext)) { return; } CoreSession session = ctx.getCoreSession(); .... } }
CoreSessions can be injected on a Bean, example:
@Name("easysoaImport") @Scope(ScopeType.CONVERSATION) @Install(precedence = Install.FRAMEWORK) public class ScaImportBean { private static Log log = LogFactory.getLog(ScaImportBean.class); @In(create = true, required = false) CoreSession documentManager; .... }
Example from the EasySOA discovery API (in the easysoa-registry-rest bundle):
@Path("easysoa/discovery") public class DiscoveryRest { @POST @Path("/appliimpl") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_JSON) public Object doPostAppliImpl(@Context HttpContext httpContext, @Context HttpServletRequest request) throws Exception { CoreSession session = SessionFactory.getSession(request); ...... } }
Example from org.nuxeo.ecm.platform.mail.listener.MailEventListener:
// open a system session loginContext = Framework.login(); RepositoryManager mgr = Framework.getService(RepositoryManager.class); Repository repository = mgr.getDefaultRepository(); if (repository != null) { coreSession = repository.open(); }
Note: other login() functions are also available, including login(String username, Object password)
.
In the case of events triggered by the scheduler (Quartz), the login part is unnecessary if you configured an username in your contribution.
Create a class that extends org.nuxeo.ecm.core.api.UnrestrictedSessionRunner, then launch it by using the runUnrestricted() method. See for example the EasySOAInitComponent + DomainInit use:
new DomainInit(defaultRepository.getName()).runUnrestricted();
public class DomainInit extends UnrestrictedSessionRunner { public DomainInit(String repositoryName) { super(repositoryName); } public void run() throws ClientException { DocumentModel root = session.getChildren( this.session.getRootDocument().getRef()).get(0); ..... } }
Any Resource registered by a WebEngineModule can access a WebContext
object which holds a CoreSession.
Use the @Inject annotation:
@RunWith(FeaturesRunner.class) @Features(EasySOACoreTestFeature.class) @RepositoryConfig(type=BackendType.H2, user = "Administrator", init=EasySOARepositoryInit.class) public class DocumentServiceTest { @Inject DocumentService docService; @Inject CoreSession session; .... }
Transactions can be configured in Nuxeo using following ways :
- in seam UI, jboss seam annotations @Transactional
- in webengine ui, one transaction around each UI request (session in view pattern), save if disabled or XML-configured otherwise on some URL patterns. See http://doc.nuxeo.com/display/NXDOC/Session+And+Transaction+Management
- in async events, AsyncEventExecutor execute a ReconnectedEventBundleImpl in its transaction thanks to EventBundleTransactionHandler, which uses TransactionHelper with custom retry & timeout.
- in services, @Transacted method annotation (used nowhere ??) : if TransactedServiceProvider is in use, Framework.getLocalService() will provide an instance of the service that is wrapped by a proxy by TransactedInstanceHandler.newProxy() that does a transaction (using TransactionHelper) around calls to @Transacted-annotated methods.
- in tests, TransactionalFeature. Uses TransactionHelper.
Additional helpers :
- TransactionHelper : explictly manage user transactions (Nuxeo's JTA Transaction manager's UserTransaction)
- TransactionalCoreSessionWrapper : Wrapper around a CoreSession that gives it transactional behavior (including events). Uses TransactionHelper.