Hi,

The code below does have a producer for the transaction. But it threw an exception.
I changed the code slightly now but am still getting the same exception.

public class ConversationListener {

    @ApplicationScopedDb
    @Inject
    NakedGraph db;

    @ConversationScoped
    @Produces
    public Transaction getTransaction() {
        db.setTransactionMode(Mode.MANUAL);
        db.startTransaction();
        return db.getTransaction();
    }

public void onStartConversation(@Observes StartConversationEvent event, Transaction t) {
        System.out.println(t);
    }

public void onCloseConversation(@Observes CloseConversationEvent event) {
        db.stopTransaction(Conclusion.SUCCESS);
    }

}

The StartConversationEvent is fired but the transaction parameter can not be resolved. Getting 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.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:127) at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.invoke(NormalScopedBeanInterceptorHandler.java:95) at org.javassist.tmp.java.lang.Object_$$_javassist_26.toString(Object_$$_javassist_26.java)
    at java.lang.String.valueOf(String.java:2838)
    at java.io.PrintStream.println(PrintStream.java:788)
at org.nakeduml.environment.ConversationListener.onStartConversation(ConversationListener.java:38)

Not sure why the producer method can not be called. Is the producer method incorrect, does it need a qualifier?

Thanks
Pieter

On 02/08/2011 21:19, Gerhard Petracek wrote:
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