hi pieter, ok - in this case that won't work (that's a logical cycle). i thought more about a producer which creates a dependent scoped transaction. however, as i see that won't help you in this special case. imo something like a lazy transaction should work. i'll think about it and create a demo.
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/3 Pieter Martin <[email protected]> > 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.**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) > 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 >>> >>> >>> >>> >>> >

