hi pieter,

the concept of outjection is deprecated.

you could create a producer method for the transaction.
if you need the transaction in an observer, you just have to add it as
additional parameter and the produced transaction will be injected into the
observer method by cdi.

regards,
gerhard

http://www.irian.at

Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German

Professional Support for Apache MyFaces




2011/8/2 Pieter Martin <[email protected]>

> Hi,
>
> I have the following requirement / problem.
>
> I would like to implement a long running transaction that is in sync with a
> conversation. I.e. I want to start a transaction when the conversation
> starts and commit the transaction when the conversation ends.
>
> So the transaction will be suspended and resumed in between requests.
>
> So far I am able to observe the StartConversationEvent and start a
> transaction. But I do not know how then to make sure that the transaction
> will be available in the conversation context.
>
> The code is as follows.
>
> @RequestScoped
> public class ConversationListener {
>
>    @ApplicationScopedDb
>    @Inject
>    NakedGraph db;
>    Transaction transaction;
>
>    @ConversationScoped
>    @Produces
>    public Transaction getTransaction() {
>        return this.transaction;
>    }
>
>    public void onStartConversation(@Observes StartConversationEvent event)
> {
>        db.startTransaction();
>        transaction = db.getTransaction();
>        // Force producer to be called, to plonk the transaction in the
>        // conversation
>        // Like seam 2 outjection
>        Transaction t = getInstance(Transaction.class)**;
>        //This throws a NullPointerException
>        t.toString();
>    }
>
>    public void onCloseConversation(@Observes CloseConversationEvent event)
> {
>        //The faces listener would have made sure the correct transaction is
> associated with this thread
>        db.stopTransaction(Conclusion.**SUCCESS);
>    }
>
>    public <T> T getInstance(Class<T> type, Annotation... qualifiers) {
>        BeanManager beanManager = getBeanManager();
>        Bean<T> bean = (Bean<T>) 
> beanManager.resolve(**beanManager.getBeans(type,
> qualifiers));
>        CreationalContext<?> ctx = beanManager.**
> createCreationalContext(bean);
>        return (T) beanManager.getReference(bean, type, ctx);
>    }
>
>    private BeanManager getBeanManager() {
>        return BeanManagerProvider.**getInstance().getBeanManager()**;
>    }
>
> }
>
> The above code does not work, it throws the following exception
>
> Caused by: java.lang.NullPointerException
>    at org.apache.myfaces.extensions.**cdi.core.impl.scope.**conversation.*
> *ConversationContextAdapter.**get(**ConversationContextAdapter.**java:100)
>    at org.apache.webbeans.context.**CustomContextImpl.get(**
> CustomContextImpl.java:48)
>    at org.apache.webbeans.context.**CustomPassivatingContextImpl.**get(**
> CustomPassivatingContextImpl.**java:47)
>    at org.apache.webbeans.intercept.**NormalScopedBeanInterceptorHan**
> dler.getContextualInstance(**NormalScopedBeanInterceptorHan**
> dler.java:127)
>    at org.apache.webbeans.intercept.**NormalScopedBeanInterceptorHan**
> dler.invoke(**NormalScopedBeanInterceptorHan**dler.java:95)
>    at org.javassist.tmp.java.lang.**Object_$$_javassist_26.**
> toString(Object_$$_javassist_**26.java)
>
> If this were to work the idea is then to suspend and resume the code in
> faces listeners
>
> @RequestScoped
> public class FacesListener {
>    @ApplicationScopedDb
>    @Inject
>    NakedGraph db;
>    @Inject
>    Logger logger;
>
>    public void beforeFacesRequest(@Observes @BeforeFacesRequest
> FacesContext ctx) {
>        logger.fine("**beforeFacesRequest, setting db on thread");
>        GraphDb.setDb(db);
>        //Need to check here somehow if a conversation has been started or
> not.
>        Transaction t = CdiEnvironment.getInstance().**
> getComponent(Transaction.**class);
>        db.resume(t);
>    }
>
>    public void afterFacesRequest(@Observes @AfterFacesRequest FacesContext
> ctx) {
>        logger.fine("**afterFacesRequest, suspend transaction and removing
> db from thread");
>        Transaction t = db.suspend();
>        //Do not need to anything with this transaction as it is already in
> the conversation context
>        GraphDb.remove();
>    }
>
> }
>
> Hope it makes sense.
> Is there a (better) way to do this?
>
> Thanks
> Pieter
>
>
>
>

Reply via email to