Re: Long transactions
Mike you left out the obvious one, simply use a conversation framework. The problem is not transactions but it is that the entity manger is dropped along the way hence silently detaching all objects and running you into detached error hell. (You still can either setup your jpa provider so that lazy loading can happen outside of transaction barriers or prefetch everything via fetch join) I personally found as soon as you go to a conversation framework things become way easier (although not entirely easy) Also what was the problem with holder objects. I personally am thinking of moving that way especially since JPA allows to map it transparently via queries like following select new FakeHolder(entity.id, entity) from EntityClass entity). The downside is that you need more logic for pushing the data back into the entity objects before writing. But the fake holder pattern is exactly what iBatis enforces (although it has the write back logic pushed into the configuration) and it works out well in a web centric szenario. WErner Am 01.07.10 23:54, schrieb Mike Kienenberger: I am, sort of. You really can't leave the transaction open beyond the request response as it may never complete. Some of the ways you can deal with it are: 1) work with fake holder entities that get changed back into real entities at the final commit. Very ugly -- tried this one at first, but I don't use it anymore. 2) Work with detached objects. Reattach them back right before the final commit. This is what I currently do.I basically invented a Unit-Of-Work framework that runs over the top of JPA.The unit of work has a separate persistence manager that loads an object, then immediately detaches it. Our framework requires each object to call save() to commit changes. When in the UoW, all save does is add the object to a change-tracker (inserts, deletes, updates).Then when the UoW is committed, the objects are persisted or merged, then committed all in one method call. But in all honesty, this approach also has caused us a lot of hassles. We are most likely going to dump JPA and replace it with Apache Cayenne, which uses a real unit of work concept. Another option for you might be to use an implementation-specific unit of work provided by your JPA implementation. However, I don't know if you might have other issues. I used Cayenne before I used JPA, and I know Cayenne does exactly what I need. A third option you could consider if you want to risk leaving the transaction open. a) Catch the window onunload event, and mixed with ajax, send an ajax request when the user improperly attempts to leave the page (closes the window or browser, enters a url directly, back buttons, some other non-transaction-friendly link clicked). I got this far with that approach, but didn't pursue it. Note that this can only detect when the user is about to leave the page. It cannot do anything at that point -- you'd have to do something about it in some other way. window.onbeforeunload = confirmExit; function confirmExit() { if (needToConfirm) return You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?; } b) Some other kind of client-side state tracking so that you know when the user has navigated away from the current multi-request task. We're sticking a taskGroupIdentifier field on every form (ajax included) so we know when the user does something to switch to a new task than the one we're currently working with. Doesn't help if you have some transaction left open and the user never hits the web server again, but a timeout could deal with that. In short, I think it's a difficult problem, and I think JPA is incapable of dealing with it correctly. The other shortfall we have is that JPA cannot rollback a transaction. You have no way of knowing what state your application is in once you roll back the transaction. Again Cayenne automatically puts everything exactly where it was at the start of your unit of work if you do a rollback. On Thu, Jul 1, 2010 at 9:53 AM, Bruno Arandabrunoara...@gmail.com wrote: Hi, Is anyone here using long JPA transactions in their applications (transactions that span more than one request) but not using Orchestra?. How are you doing it? Cheers, Bruno
Re: Long transactions
Mike you left out the obvious one, simply use a conversation framework. Definitely true, but not always applicable. I would e.g. not recommend using long running transactions for public pages. This will increase the session footprint big times and you'll get more easily vulnerable for DOS attacks this way. Otoh, for intranet apps or pages with a limited reach, frameworks like Orchestra will really make your life way easier. FYI: we are currently working on getting Orchestra style conversations ported over to our MyFaces Extensions for CDI (EXTCDI / CODI). LieGrue, strub - Original Message From: Werner Punz werner.p...@gmail.com To: users@myfaces.apache.org Sent: Fri, July 2, 2010 9:39:05 AM Subject: Re: Long transactions Mike you left out the obvious one, simply use a conversation framework. The problem is not transactions but it is that the entity manger is dropped along the way hence silently detaching all objects and running you into detached error hell. (You still can either setup your jpa provider so that lazy loading can happen outside of transaction barriers or prefetch everything via fetch join) I personally found as soon as you go to a conversation framework things become way easier (although not entirely easy) Also what was the problem with holder objects. I personally am thinking of moving that way especially since JPA allows to map it transparently via queries like following select new FakeHolder( target=_blank href=http://entity.id;entity.id, entity) from EntityClass entity). The downside is that you need more logic for pushing the data back into the entity objects before writing. But the fake holder pattern is exactly what iBatis enforces (although it has the write back logic pushed into the configuration) and it works out well in a web centric szenario. WErner Am 01.07.10 23:54, schrieb Mike Kienenberger: I am, sort of. You really can't leave the transaction open beyond the request response as it may never complete. Some of the ways you can deal with it are: 1) work with fake holder entities that get changed back into real entities at the final commit. Very ugly -- tried this one at first, but I don't use it anymore. 2) Work with detached objects. Reattach them back right before the final commit. This is what I currently do.I basically invented a Unit-Of-Work framework that runs over the top of JPA.The unit of work has a separate persistence manager that loads an object, then immediately detaches it. Our framework requires each object to call save() to commit changes. When in the UoW, all save does is add the object to a change-tracker (inserts, deletes, updates). Then when the UoW is committed, the objects are persisted or merged, then committed all in one method call. But in all honesty, this approach also has caused us a lot of hassles. We are most likely going to dump JPA and replace it with Apache Cayenne, which uses a real unit of work concept. Another option for you might be to use an implementation-specific unit of work provided by your JPA implementation. However, I don't know if you might have other issues. I used Cayenne before I used JPA, and I know Cayenne does exactly what I need. A third option you could consider if you want to risk leaving the transaction open. a) Catch the window onunload event, and mixed with ajax, send an ajax request when the user improperly attempts to leave the page (closes the window or browser, enters a url directly, back buttons, some other non-transaction-friendly link clicked). I got this far with that approach, but didn't pursue it. Note that this can only detect when the user is about to leave the page. It cannot do anything at that point -- you'd have to do something about it in some other way. window.onbeforeunload = confirmExit; function confirmExit() { if (needToConfirm) return You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?; } b) Some other kind of client-side state tracking so that you know when the user has navigated away from the current multi-request task. We're sticking a taskGroupIdentifier field on every form (ajax included) so we know when the user does something to switch to a new task than the one we're currently working with. Doesn't help if you have some transaction left open and the user never hits the web server again, but a timeout could deal with that. In short, I think it's a difficult problem, and I think JPA is incapable of dealing with it correctly. The other shortfall we have is that JPA cannot rollback a transaction. You have no way of
Re: Problem with Ajax and ViewScope
Hi Werner, I tested the problem with newest snapshot from today and it works. It looks like it was a temporary bug in the trunk. ;-) Thx for your help! Marcus Werner Punz schrieb: Ok I gave the example a testrun and could not reproduce the problem anymore, I assume one of following issues a) It was a temporary bug in the trunk (I did an svn update on the latest codebase to check) b) You might have forgotten to make the ViewScoped bean serializable. (In which case the latest trunk issues an error and the latest ajax scripts as well) c) Your event handlers supress the phases In either case with a stock serializable page scoped bean thew example works as expected. I have closed the issue for now, please give me notice if the latest trunk works for you, if not we will investigate a little bit more. Werner Am 29.06.10 12:56, schrieb Marcus Büttner: Thx for your response. I created an issue. https://issues.apache.org/jira/browse/MYFACES-2776 Marcus Werner Punz schrieb: Hi there is some optimization work going on currently on the viewstate, you might have triggered a bug in the trunk, can you file a jira issue on this one? Werner Am 29.06.10 11:05, schrieb Marcus Büttner: Hi, a small example with two input fields, both with valueChangeListener and a f:ajax for rerendering the output field: h:form id=myForm h:outputLabel for=val1 value=Value1/ h:inputText id=val1 value=#{myBean.val1} valueChangeListener=#{myBean.val1ChangedListener} f:ajax render=myText event=change / /h:inputText h:outputLabel for=val2 value=Value2/ h:inputText id=val2 value=#{myBean.val2} valueChangeListener=#{myBean.val2ChangedListener} f:ajax render=myText event=change / /h:inputText h:outputText id=myText value=#{myBean.val1} #{myBean.val2}/ /h:form Everything works fine, until my Bean is ViewScoped. Every time I change a value in the input fields, this value is rendered in my output. But all changes before are lost. E.g. change value1 to value1 causes output = value1 change value2 to value2 causes output = value2 (but it should be: value1 value2) I've debugged and found, that in restoreView always the first ViewState (which was active after entering the page) is restored. It looks like, the javax.faces.ViewState component in html DOM tree is not updated by an ajax request and so always the first ViewState is restored instead of the last. I'm using the last MyFaces Snapshot (2.0.1-SNAPSHOT). Does anyone has an idea? Or is something wrong in my code? Thx for help. Regards Marcus
Re: Long transactions
Hi! I know, I might sound like a broken record already ... But also consider using a JPA-like persistence provider like Ebean [1]. If you are going to deatach your objects, you can avoid the persistence context at all. Ebean just maintains a persistence context per transaction. So, if you are having processes which reads the same row from the database multiple times you'll get the same instance from the cache, but reads outside of a transaction result in immediately detached object. For sure, without the persistence context you have to call ebean.save(instance) on your entities instead of relying on a session.commit(), but this is a very low price to pay compared to all the hassle you have with a long running persistence context. Lazy loading is still possible with Ebean anyway! And not only this, it also learns (if configured) from your application which relations you use and which properties and next time will autotune the select to just fetch those properties and relation. No need to define a 1:n relation eager or lazy, it just learns that (optional for sure!). I can say, I am quite happy with this library! I even replaced Hibernate by it. Probably you have to put some effort into the transition, but for me it made things alot easier again. Ciao, Mario [1] www.avaje.org -Ursprüngliche Nachricht- Von: Mark Struberg [mailto:strub...@yahoo.de] Gesendet: Freitag, 02. Juli 2010 10:12 An: MyFaces Discussion Betreff: Re: Long transactions Mike you left out the obvious one, simply use a conversation framework. Definitely true, but not always applicable. I would e.g. not recommend using long running transactions for public pages. This will increase the session footprint big times and you'll get more easily vulnerable for DOS attacks this way. Otoh, for intranet apps or pages with a limited reach, frameworks like Orchestra will really make your life way easier. FYI: we are currently working on getting Orchestra style conversations ported over to our MyFaces Extensions for CDI (EXTCDI / CODI). LieGrue, strub - Original Message From: Werner Punz werner.p...@gmail.com To: users@myfaces.apache.org Sent: Fri, July 2, 2010 9:39:05 AM Subject: Re: Long transactions Mike you left out the obvious one, simply use a conversation framework. The problem is not transactions but it is that the entity manger is dropped along the way hence silently detaching all objects and running you into detached error hell. (You still can either setup your jpa provider so that lazy loading can happen outside of transaction barriers or prefetch everything via fetch join) I personally found as soon as you go to a conversation framework things become way easier (although not entirely easy) Also what was the problem with holder objects. I personally am thinking of moving that way especially since JPA allows to map it transparently via queries like following select new FakeHolder( target=_blank href=http://entity.id;entity.id, entity) from EntityClass entity). The downside is that you need more logic for pushing the data back into the entity objects before writing. But the fake holder pattern is exactly what iBatis enforces (although it has the write back logic pushed into the configuration) and it works out well in a web centric szenario. WErner Am 01.07.10 23:54, schrieb Mike Kienenberger: I am, sort of. You really can't leave the transaction open beyond the request response as it may never complete. Some of the ways you can deal with it are: 1) work with fake holder entities that get changed back into real entities at the final commit. Very ugly -- tried this one at first, but I don't use it anymore. 2) Work with detached objects. Reattach them back right before the final commit. This is what I currently do.I basically invented a Unit-Of-Work framework that runs over the top of JPA.The unit of work has a separate persistence manager that loads an object, then immediately detaches it. Our framework requires each object to call save() to commit changes. When in the UoW, all save does is add the object to a change-tracker (inserts, deletes, updates). Then when the UoW is committed, the objects are persisted or merged, then committed all in one method call. But in all honesty, this approach also has caused us a lot of hassles. We are most likely going to dump JPA and replace it with Apache Cayenne, which uses a real unit of work concept. Another option for you might be to use an implementation-specific unit of work provided by your JPA implementation. However, I don't know if you might have other issues. I used Cayenne before I used JPA, and I know Cayenne does exactly what I need. A third option you could consider if you want to risk leaving the transaction open. a) Catch the window onunload event, and mixed with ajax, send an ajax request
Re: Long transactions
And, btw, Orchestra is still useful then, but there is no need to attach it to the PersistenceContext then. It just acts as a simple conversation scope provider without any magic associated with the database layer. = easier spring configuration too. Ciao, Mario -Ursprüngliche Nachricht- Von: Mario Ivankovits [mailto:ma...@ops.co.at] Gesendet: Freitag, 02. Juli 2010 10:27 An: 'MyFaces Discussion' Betreff: Re: Long transactions Hi! I know, I might sound like a broken record already ... But also consider using a JPA-like persistence provider like Ebean [1]. If you are going to deatach your objects, you can avoid the persistence context at all. Ebean just maintains a persistence context per transaction. So, if you are having processes which reads the same row from the database multiple times you'll get the same instance from the cache, but reads outside of a transaction result in immediately detached object. For sure, without the persistence context you have to call ebean.save(instance) on your entities instead of relying on a session.commit(), but this is a very low price to pay compared to all the hassle you have with a long running persistence context. Lazy loading is still possible with Ebean anyway! And not only this, it also learns (if configured) from your application which relations you use and which properties and next time will autotune the select to just fetch those properties and relation. No need to define a 1:n relation eager or lazy, it just learns that (optional for sure!). I can say, I am quite happy with this library! I even replaced Hibernate by it. Probably you have to put some effort into the transition, but for me it made things alot easier again. Ciao, Mario [1] www.avaje.org -Ursprüngliche Nachricht- Von: Mark Struberg [mailto:strub...@yahoo.de] Gesendet: Freitag, 02. Juli 2010 10:12 An: MyFaces Discussion Betreff: Re: Long transactions Mike you left out the obvious one, simply use a conversation framework. Definitely true, but not always applicable. I would e.g. not recommend using long running transactions for public pages. This will increase the session footprint big times and you'll get more easily vulnerable for DOS attacks this way. Otoh, for intranet apps or pages with a limited reach, frameworks like Orchestra will really make your life way easier. FYI: we are currently working on getting Orchestra style conversations ported over to our MyFaces Extensions for CDI (EXTCDI / CODI). LieGrue, strub - Original Message From: Werner Punz werner.p...@gmail.com To: users@myfaces.apache.org Sent: Fri, July 2, 2010 9:39:05 AM Subject: Re: Long transactions Mike you left out the obvious one, simply use a conversation framework. The problem is not transactions but it is that the entity manger is dropped along the way hence silently detaching all objects and running you into detached error hell. (You still can either setup your jpa provider so that lazy loading can happen outside of transaction barriers or prefetch everything via fetch join) I personally found as soon as you go to a conversation framework things become way easier (although not entirely easy) Also what was the problem with holder objects. I personally am thinking of moving that way especially since JPA allows to map it transparently via queries like following select new FakeHolder( target=_blank href=http://entity.id;entity.id, entity) from EntityClass entity). The downside is that you need more logic for pushing the data back into the entity objects before writing. But the fake holder pattern is exactly what iBatis enforces (although it has the write back logic pushed into the configuration) and it works out well in a web centric szenario. WErner Am 01.07.10 23:54, schrieb Mike Kienenberger: I am, sort of. You really can't leave the transaction open beyond the request response as it may never complete. Some of the ways you can deal with it are: 1) work with fake holder entities that get changed back into real entities at the final commit. Very ugly -- tried this one at first, but I don't use it anymore. 2) Work with detached objects. Reattach them back right before the final commit. This is what I currently do.I basically invented a Unit-Of-Work framework that runs over the top of JPA.The unit of work has a separate persistence manager that loads an object, then immediately detaches it. Our framework requires each object to call save() to commit changes. When in the UoW, all save does is add the object to a change-tracker (inserts, deletes, updates). Then when the UoW is committed, the objects are persisted or merged, then committed all in one method call. But in all honesty, this approach also has caused us a lot of hassles. We are most likely going to dump JPA and replace it with Apache Cayenne, which uses a real unit of work
Re: MyFaces JSF-Portlet Bridge and Facelets
Thanks for your response. I have not had a chance to look at the Facelets example in trunk yet and compare that to my code but it's good to know it's there. I'll report back once I have some results. Rossen On 06/17/2010 11:01 AM, Michael Freedman wrote: So I tried running the (new) facelets example that is part of the bridge project using MyFaces 1.2.2 on Jetty/Pluto and all worked as expected. I was verifying the portlet 1.0 bridge version NOT the portlet 2.0 bridge version -- but the examples are the same. Did you get a chance to try the example? How does it differ from what you have done? -Mike-
concurrency problem ajax value change event and page submit
Hi, I have the following example: h:outputLabel for=val1 value=Value1/ h:inputText id=val1 value=#{myBean.val1} valueChangeListener=#{myBean.val1ChangedListener} f:ajax render=myText event=change / /h:inputText h:outputText id=myText value=#{myBean.val1}/ h:commandButton id=button value=submit action=#{myBean.action}/ Now I fill out the input field and directly press Enter for submit or click submit button without leaving the input field before. Now two requests are send parallel (page submit and ajax value change event). The problem is I found four different behaviours which comes random (with firefox): 1.) 1. request: value change listener is called. 2. request actions is called (that's what I expected) 2.) 1. request value change listener is called. but the action request is missing. 3.) 1. action request get's in an fires the value change event and calls the action. but than this message pops up: httpError-httpError-Request failed- Note, this message is only sent, because project sage is development and no other error listeners are registered 4.) 1. request value change lister is called. 2. request also value change listener is called and than the action is called. the message above also pops up. In IE sometimes the action is called, sometimes not. The value change listener is always called. But this error dialog (like in firefox) is never shown. Is there any explanation? How could I force a fix behaviour? Thx for help. Marcus
Re: concurrency problem ajax value change event and page submit
Yes the issue is that you use a command button which in case of a single button maps automatically to input type=submit if you hit enter the ajax request is issued and subsequently parallely the full submit is issued as well. You can resolve that by using commandlinks or h:commandButton type=button which should resolve the auto enter issue introduced by the input type=submit. The problem with the error is not a bug but an xhr request issued asynchronously then a page refresh triggered at the same time which is more a problem of the spec relying on parallel xhr requests. MyFaces then correctly issues an http error due to the timing issue triggered because of the xhr request having failed due to the subsequent refresh issued. But as usual with those timing problems they occur depending on the current state of the issue, hence in a non reproducable manner. So the final behavior after fixing is change + enter - onchange button press - action Werner Am 02.07.10 13:35, schrieb Marcus Büttner: Hi, I have the following example: h:outputLabel for=val1 value=Value1/ h:inputText id=val1 value=#{myBean.val1} valueChangeListener=#{myBean.val1ChangedListener} f:ajax render=myText event=change / /h:inputText h:outputText id=myText value=#{myBean.val1}/ h:commandButton id=button value=submit action=#{myBean.action}/ Now I fill out the input field and directly press Enter for submit or click submit button without leaving the input field before. Now two requests are send parallel (page submit and ajax value change event). The problem is I found four different behaviours which comes random (with firefox): 1.) 1. request: value change listener is called. 2. request actions is called (that's what I expected) 2.) 1. request value change listener is called. but the action request is missing. 3.) 1. action request get's in an fires the value change event and calls the action. but than this message pops up: httpError-httpError-Request failed- Note, this message is only sent, because project sage is development and no other error listeners are registered 4.) 1. request value change lister is called. 2. request also value change listener is called and than the action is called. the message above also pops up. In IE sometimes the action is called, sometimes not. The value change listener is always called. But this error dialog (like in firefox) is never shown. Is there any explanation? How could I force a fix behaviour? Thx for help. Marcus
Re: Problems with orchestra and JSF 2
Hi! I have finally manager to create a very simple test case for my problem. My issue with data loss seems to be related to the enctype of the form (multipart/form-data) and the fact that I am loading data using a preRenderView event. To reproduce this problem, create a test page: html xmlns=http://www.w3.org/1999/xhtml; xmlns:h=http://java.sun.com/jsf/html; xmlns:f=http://java.sun.com/jsf/core; xmlns:ui=http://java.sun.com/jsf/facelets; f:view contentType=text/html h:body h:form prependId=false enctype=multipart/form-data f:metadata f:event type=preRenderView listener=#{playgroundController.load}/ /f:metadata h:inputText value=#{playgroundController.car.colour}/ h:inputText value=#{playgroundController.car.make}/ h:outputText value=#{playgroundController.car}/ h:commandButton value=Talk actionListener=#{playgroundController.talk}/ /h:form /h:body /f:view /html With a backing bean behind: @Controller @Scope( conversation.access ) public class PlaygroundController implements Serializable { private Car car; public PlaygroundController() { System.out.println(\nNEW PLAY INSTANCE +Integer.toHexString(hashCode())+\n); } public void load() { System.out.println(\nLOAD +Integer.toHexString(hashCode())+\n); car = new Car(); } public void talk(ActionEvent evt) { System.out.println(CAR: +car); } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } } If the enctype is multipart/form-data, when I click on the submit button, the bean will be instantiated again and the load method won't be called... throwing an ugly exception. If the enctype is the default, everything works as expected and the method talk(ActionEvent evt) will print the car in the console as expected. I am using multipart/form-data because I wanted to upload some files. I can see it is troublesome... anyone could explain me why? Thanks! Bruno On 1 July 2010 17:09, Bruno Aranda brunoara...@gmail.com wrote: Hi, No I do not use portlets. I am now writing a simple test case, to see if I can reproduce it. With the simplest case, everything is working as expected, so there has to be some conflict with the rest of the application (e.g. Spring 3 proxies, the transaction manager or something else). I am investigating to see if I can reproduce it... The conversationContext is fine in both scenarios... Bruno On 1 July 2010 16:50, Mario Ivankovits ma...@ops.co.at wrote: Heya! Please check the url parameter conversationContext has been added to each and every url. If it is missing, a new context will be created each request and then a new bean will be created too. Now you sure would like to know why it is missing ... if it is missing. Hmmm ... do you use portlets or such? Ciao, Mario PS: Sorry for top-posting, Mail-Client oddities ... :) -Ursprüngliche Nachricht- Von: Bruno Aranda [mailto:brunoara...@gmail.com] Gesendet: Donnerstag, 01. Juli 2010 14:42 An: MyFaces Discussion Betreff: Re: Problems with orchestra and JSF 2 What I can see as well after putting a method with the @PostConstruct annotation, is that this method is called every request, as if the conversation didn't exist before, which is not true. I am outputting the orchestra logs in the console, and I can see: 2010-07-01 14:05:32,729 [qtp33228489-20] DEBUG (DebugPhaseListener,40) - Before phase: RESTORE_VIEW(1) 2010-07-01 14:05:32,823 [qtp33228489-20] DEBUG (Conversation,108) - start conversation:general NEW INSTANCE PUBCONTROLLER HASH: 9f720d POST CONS PUB === 9f720d NEW INSTANCE PUBCONTROLLER HASH: 147f75 NEW INSTANCE PUBCONTROLLER HASH: 1bbefe8 2010-07-01 14:05:32,844 [qtp33228489-20] DEBUG (Conversation,176) - put bean to conversation:org.springframework.beans.factory.support.Dispo sablebeanadap...@25394361 (bean=org.apache.myfaces.orchestra.conversation.spring.AbstractSpringOrchest rascop...@17167e6 ) 2010-07-01 14:05:32,846 [qtp33228489-20] DEBUG (Conversation,176) - put bean to conversation:org.apache.myfaces.orchestra.conversation.sprin g.PersistenceContextConversationInterceptor.PERSISTENCE_CONTEXT(bean=org.apa che.myfaces.orchestra.conversation.spring.PersistenceContextClos e...@81f22c) 2010-07-01 14:05:32,847 [qtp33228489-20] DEBUG (Conversation,176) - put bean to conversation:publicationController(bean=uk.ac.ebi.intact.edi tor.controller.curate.publication.publicationcontrol...@9f720d) 2010-07-01 14:05:32,853 [qtp33228489-20] DEBUG (DebugPhaseListener,35) - After phase: RESTORE_VIEW(1) ... The bean is called publicationController, which should be maintained in a conversation called general. And I see this every request. This is the bean class annotations: @Controller @Scope( conversation.access ) @ConversationName(
Re: Long transactions
I am not familiar with orchestra, so I can't comment there. It has not been an option for us up to this point. However, if you leave a transaction active after a response, it's always going to be an issue no matter what framework you use. For us, the problem with holder objects is the deep hierarchy of entities and relationships we have. We have probably close to a thousand entities right now, and most multiple-request-spanning transactions deal with very complex, deep, and width relationship paths. They only work well in the simple cases where we don't need them. On Fri, Jul 2, 2010 at 3:39 AM, Werner Punz werner.p...@gmail.com wrote: Mike you left out the obvious one, simply use a conversation framework. The problem is not transactions but it is that the entity manger is dropped along the way hence silently detaching all objects and running you into detached error hell. (You still can either setup your jpa provider so that lazy loading can happen outside of transaction barriers or prefetch everything via fetch join) I personally found as soon as you go to a conversation framework things become way easier (although not entirely easy) Also what was the problem with holder objects. I personally am thinking of moving that way especially since JPA allows to map it transparently via queries like following select new FakeHolder(entity.id, entity) from EntityClass entity). The downside is that you need more logic for pushing the data back into the entity objects before writing. But the fake holder pattern is exactly what iBatis enforces (although it has the write back logic pushed into the configuration) and it works out well in a web centric szenario. WErner Am 01.07.10 23:54, schrieb Mike Kienenberger: I am, sort of. You really can't leave the transaction open beyond the request response as it may never complete. Some of the ways you can deal with it are: 1) work with fake holder entities that get changed back into real entities at the final commit. Very ugly -- tried this one at first, but I don't use it anymore. 2) Work with detached objects. Reattach them back right before the final commit. This is what I currently do. I basically invented a Unit-Of-Work framework that runs over the top of JPA. The unit of work has a separate persistence manager that loads an object, then immediately detaches it. Our framework requires each object to call save() to commit changes. When in the UoW, all save does is add the object to a change-tracker (inserts, deletes, updates). Then when the UoW is committed, the objects are persisted or merged, then committed all in one method call. But in all honesty, this approach also has caused us a lot of hassles. We are most likely going to dump JPA and replace it with Apache Cayenne, which uses a real unit of work concept. Another option for you might be to use an implementation-specific unit of work provided by your JPA implementation. However, I don't know if you might have other issues. I used Cayenne before I used JPA, and I know Cayenne does exactly what I need. A third option you could consider if you want to risk leaving the transaction open. a) Catch the window onunload event, and mixed with ajax, send an ajax request when the user improperly attempts to leave the page (closes the window or browser, enters a url directly, back buttons, some other non-transaction-friendly link clicked). I got this far with that approach, but didn't pursue it. Note that this can only detect when the user is about to leave the page. It cannot do anything at that point -- you'd have to do something about it in some other way. window.onbeforeunload = confirmExit; function confirmExit() { if (needToConfirm) return You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?; } b) Some other kind of client-side state tracking so that you know when the user has navigated away from the current multi-request task. We're sticking a taskGroupIdentifier field on every form (ajax included) so we know when the user does something to switch to a new task than the one we're currently working with. Doesn't help if you have some transaction left open and the user never hits the web server again, but a timeout could deal with that. In short, I think it's a difficult problem, and I think JPA is incapable of dealing with it correctly. The other shortfall we have is that JPA cannot rollback a transaction. You have no way of knowing what state your application is in once you roll back the transaction. Again Cayenne automatically puts everything exactly where it was at the start of your unit of work if you do a rollback. On Thu, Jul 1, 2010 at
Re: Problems with orchestra and JSF 2
Hi It is not a problem related to orchestra. JSF implementation does not decode request with enctype=multipart/form-data. Other user reported this on: https://issues.apache.org/jira/browse/MYFACES-2688 For decode that kind of requests it is necessary to use a filter or a FacesContextWrapper. Tomahawk is one option (using ExtensionFilter or TomahawkFacesContextWrapper), but Trinidad and other jsf libraries usually has filters that do that. regards, Leonardo Uribe 2010/7/2 Bruno Aranda brunoara...@gmail.com Hi! I have finally manager to create a very simple test case for my problem. My issue with data loss seems to be related to the enctype of the form (multipart/form-data) and the fact that I am loading data using a preRenderView event. To reproduce this problem, create a test page: html xmlns=http://www.w3.org/1999/xhtml; xmlns:h=http://java.sun.com/jsf/html; xmlns:f=http://java.sun.com/jsf/core; xmlns:ui=http://java.sun.com/jsf/facelets; f:view contentType=text/html h:body h:form prependId=false enctype=multipart/form-data f:metadata f:event type=preRenderView listener=#{playgroundController.load}/ /f:metadata h:inputText value=#{playgroundController.car.colour}/ h:inputText value=#{playgroundController.car.make}/ h:outputText value=#{playgroundController.car}/ h:commandButton value=Talk actionListener=#{playgroundController.talk}/ /h:form /h:body /f:view /html With a backing bean behind: @Controller @Scope( conversation.access ) public class PlaygroundController implements Serializable { private Car car; public PlaygroundController() { System.out.println(\nNEW PLAY INSTANCE +Integer.toHexString(hashCode())+\n); } public void load() { System.out.println(\nLOAD +Integer.toHexString(hashCode())+\n); car = new Car(); } public void talk(ActionEvent evt) { System.out.println(CAR: +car); } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } } If the enctype is multipart/form-data, when I click on the submit button, the bean will be instantiated again and the load method won't be called... throwing an ugly exception. If the enctype is the default, everything works as expected and the method talk(ActionEvent evt) will print the car in the console as expected. I am using multipart/form-data because I wanted to upload some files. I can see it is troublesome... anyone could explain me why? Thanks! Bruno On 1 July 2010 17:09, Bruno Aranda brunoara...@gmail.com wrote: Hi, No I do not use portlets. I am now writing a simple test case, to see if I can reproduce it. With the simplest case, everything is working as expected, so there has to be some conflict with the rest of the application (e.g. Spring 3 proxies, the transaction manager or something else). I am investigating to see if I can reproduce it... The conversationContext is fine in both scenarios... Bruno On 1 July 2010 16:50, Mario Ivankovits ma...@ops.co.at wrote: Heya! Please check the url parameter conversationContext has been added to each and every url. If it is missing, a new context will be created each request and then a new bean will be created too. Now you sure would like to know why it is missing ... if it is missing. Hmmm ... do you use portlets or such? Ciao, Mario PS: Sorry for top-posting, Mail-Client oddities ... :) -Ursprüngliche Nachricht- Von: Bruno Aranda [mailto:brunoara...@gmail.com] Gesendet: Donnerstag, 01. Juli 2010 14:42 An: MyFaces Discussion Betreff: Re: Problems with orchestra and JSF 2 What I can see as well after putting a method with the @PostConstruct annotation, is that this method is called every request, as if the conversation didn't exist before, which is not true. I am outputting the orchestra logs in the console, and I can see: 2010-07-01 14:05:32,729 [qtp33228489-20] DEBUG (DebugPhaseListener,40) - Before phase: RESTORE_VIEW(1) 2010-07-01 14:05:32,823 [qtp33228489-20] DEBUG (Conversation,108) - start conversation:general NEW INSTANCE PUBCONTROLLER HASH: 9f720d POST CONS PUB === 9f720d NEW INSTANCE PUBCONTROLLER HASH: 147f75 NEW INSTANCE PUBCONTROLLER HASH: 1bbefe8 2010-07-01 14:05:32,844 [qtp33228489-20] DEBUG (Conversation,176) - put bean to conversation:org.springframework.beans.factory.support.Dispo sablebeanadap...@25394361 (bean=org.apache.myfaces.orchestra.conversation.spring.AbstractSpringOrchest rascop...@17167e6 ) 2010-07-01 14:05:32,846 [qtp33228489-20] DEBUG (Conversation,176) - put bean to conversation:org.apache.myfaces.orchestra.conversation.sprin g.PersistenceContextConversationInterceptor.PERSISTENCE_CONTEXT(bean=org.apa
Re: Problems with orchestra and JSF 2
Hi, I have same problem with CDI a it's conversation. Please see my comment on https://issues.apache.org/jira/browse/MYFACES-2688 Best regards, Martin Kočí Leonardo Uribe píše v Pá 02. 07. 2010 v 13:31 -0500: Hi It is not a problem related to orchestra. JSF implementation does not decode request with enctype=multipart/form-data. Other user reported this on: https://issues.apache.org/jira/browse/MYFACES-2688 For decode that kind of requests it is necessary to use a filter or a FacesContextWrapper. Tomahawk is one option (using ExtensionFilter or TomahawkFacesContextWrapper), but Trinidad and other jsf libraries usually has filters that do that. regards, Leonardo Uribe 2010/7/2 Bruno Aranda brunoara...@gmail.com Hi! I have finally manager to create a very simple test case for my problem. My issue with data loss seems to be related to the enctype of the form (multipart/form-data) and the fact that I am loading data using a preRenderView event. To reproduce this problem, create a test page: html xmlns=http://www.w3.org/1999/xhtml; xmlns:h=http://java.sun.com/jsf/html; xmlns:f=http://java.sun.com/jsf/core; xmlns:ui=http://java.sun.com/jsf/facelets; f:view contentType=text/html h:body h:form prependId=false enctype=multipart/form-data f:metadata f:event type=preRenderView listener=#{playgroundController.load}/ /f:metadata h:inputText value=#{playgroundController.car.colour}/ h:inputText value=#{playgroundController.car.make}/ h:outputText value=#{playgroundController.car}/ h:commandButton value=Talk actionListener=#{playgroundController.talk}/ /h:form /h:body /f:view /html With a backing bean behind: @Controller @Scope( conversation.access ) public class PlaygroundController implements Serializable { private Car car; public PlaygroundController() { System.out.println(\nNEW PLAY INSTANCE +Integer.toHexString(hashCode())+\n); } public void load() { System.out.println(\nLOAD +Integer.toHexString(hashCode())+\n); car = new Car(); } public void talk(ActionEvent evt) { System.out.println(CAR: +car); } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } } If the enctype is multipart/form-data, when I click on the submit button, the bean will be instantiated again and the load method won't be called... throwing an ugly exception. If the enctype is the default, everything works as expected and the method talk(ActionEvent evt) will print the car in the console as expected. I am using multipart/form-data because I wanted to upload some files. I can see it is troublesome... anyone could explain me why? Thanks! Bruno On 1 July 2010 17:09, Bruno Aranda brunoara...@gmail.com wrote: Hi, No I do not use portlets. I am now writing a simple test case, to see if I can reproduce it. With the simplest case, everything is working as expected, so there has to be some conflict with the rest of the application (e.g. Spring 3 proxies, the transaction manager or something else). I am investigating to see if I can reproduce it... The conversationContext is fine in both scenarios... Bruno On 1 July 2010 16:50, Mario Ivankovits ma...@ops.co.at wrote: Heya! Please check the url parameter conversationContext has been added to each and every url. If it is missing, a new context will be created each request and then a new bean will be created too. Now you sure would like to know why it is missing ... if it is missing. Hmmm ... do you use portlets or such? Ciao, Mario PS: Sorry for top-posting, Mail-Client oddities ... :) -Ursprüngliche Nachricht- Von: Bruno Aranda [mailto:brunoara...@gmail.com] Gesendet: Donnerstag, 01. Juli 2010 14:42 An: MyFaces Discussion Betreff: Re: Problems with orchestra and JSF 2 What I can see as well after putting a method with the @PostConstruct annotation, is that this method is called every request, as if the conversation didn't exist before, which is not true. I am outputting the orchestra logs in the console, and I can see: 2010-07-01 14:05:32,729 [qtp33228489-20] DEBUG (DebugPhaseListener,40) - Before phase: RESTORE_VIEW(1) 2010-07-01 14:05:32,823 [qtp33228489-20] DEBUG (Conversation,108) - start conversation:general NEW INSTANCE PUBCONTROLLER HASH: 9f720d POST CONS PUB === 9f720d NEW INSTANCE PUBCONTROLLER HASH: 147f75 NEW INSTANCE PUBCONTROLLER HASH: 1bbefe8 2010-07-01 14:05:32,844 [qtp33228489-20] DEBUG (Conversation,176) - put bean to