As I’ve mentioned previously, much of my current work revolves around one database used to allow organizations to request grants for one of our projects. In doing so, when they open the XPage to request a grant, there are four separate attachment documents as source documents to the XPage, as well as the main document and a contact document. One of the issue I had with our initial roll out of the database was that users uploading their attachments ended up creating many rep/save conflicts and getting every attachments loaded on every source document except the contact document. I had no idea why, but it was in production already and with less than 100 grant requests, I simply manually fixed all the rep/saves as they created them. Basically, using a hammer to repair ceramics.
The problematic code was, unbeknownst to me, my source declarations.
<xp:this.data> <xp:dominoDocument var="workplanDoc" formName="AttachAnnex" /> <xp:dominoDocument var="projectBudgetDoc" formName="AttachAnnex" /> <xp:dominoDocument var="budgetAssumptionsDoc" formName="AttachAnnex" /> <xp:dominoDocument var="performanceIndicatorsDoc" formName="AttachAnnex" /> </xp:this.data>
I knew something was wrong. I’d originally had those four source documents declared at the top of the XPage, but when I moved them onto a custom control, it seemed to me that I’d resolved them problem. Unfortunately, I think it was only working some of the time (new grant requests, which had no documentId= in the URL, I suspect), if at all.
So, I wondered and I searched. Then, the daily compilation of Lotus Notes questions on Stack Overflow came through. The first item was labelled “XPage xe:Dialog box is edit previous create document”, which didn’t seem too interesting, but the snippet from the question raised my eyebrows, “I have a custom control that create a new document through ext-lib dialog box that work fine. However when the action is performed the second time it edit the document instead of creating a new …” I realized he was dealing with multiple data sources and having problems similar to mine. So, I opened the question and found great advice from Patrick Sawyer.
set ignoreRequestParams to true and then set the scope to request
Then, I followed links to his post to get more information, finding that even though I’d read Patrick’s question about multiple data sources and commented on it, no less, that I had no recollection of that solution (provided by Tim Tripcony!) So, I changed my code.
<xp:this.data> <xp:dominoDocument var="workplanDoc" formName="AttachAnnex" ignoreRequestParams="true" scope="view" /> <xp:dominoDocument var="projectBudgetDoc" formName="AttachAnnex" ignoreRequestParams="true" scope="view" /> <xp:dominoDocument var="budgetAssumptionsDoc" formName="AttachAnnex" ignoreRequestParams="true" scope="view" /> <xp:dominoDocument var="performanceIndicatorsDoc" formName="AttachAnnex" ignoreRequestParams="true" scope="view" /> </xp:this.data>
Tim explained the function of ignoreRequestParameters well in his answer to Patrick’s question:
If you omit the
ignoreRequestParamsattribute, then this data source doesn’t ignore the URL request parameters. Instead, it looks for parameters named
action. If any of these parameters are included in the URL, the value of each overrides what is defined on the data source.
So, what was happening was that if you started a grant request via the simple link, which was just the XPage URL, ending with “Application.XSP” then there were no parameters to worry about and the source documents might be created properly. However, if the users followed the link I’d emailed them, pointing to their specific document, with action=editDocument, and documentId= the UNID of their grant request, it would use those values and upload the attachment to main document, modify the form name to “AttachAnnex” and, with multiple uploads of many attachments, create a flurry of save conflicts. I’d go through and change form names on one of them and save the others, so they all got assigned new UNIDs.
Now, I tried both requestScope and viewScope, finally settling on viewScope. If I use requestScope, then each attachment upload creates a new Notes document with the attachment on it. If I use viewScope, then, for the span of that user session, each upload that the user does to that source document goes onto the same Notes document. If they come back and upload more documents in a separate session, it should create a new Notes document that would hold all of the attachments uploaded for that source document. So, with requestScope, if the user had 10 files to upload, some for each source document, they would be creating 10 Notes documents, regardless of whether they uploaded them in one sitting or several. With viewScope, if they uploaded 3 files to workplanDoc in one sitting, all 3 files would end up on 1 Notes document. Since I’d already worked out how to handle the linking to attachments for multi-attachment Notes documents, I chose viewScope, which keeps the attachments more organized.
Now, if I were to experiment, I expect that using sessionScope would create problems for any user who submits multiple grant requests, as it would use a four source documents for their entire session. This would put every workplan attachment onto one workplan Notes document that would end up associated only with the last grant request they edited. I could be even more foolish and grant the source documents applicationScope, which would put every attachment that any use uploaded into one of the four application-wide source documents, each time, associating it with a different grant request. Nightmarish!
I’d been wondering, and heard multiple speakers who discussed scope at various conferences say, “I’m not real sure why you’d use requestScope, but I know there are reasons.” Well, creating new source documents from an XPage that uses multiple source documents is just such a reason.