Some time ago I read Chris Toohey’s article on Logic-Driven NotesDocument UNIDs. I have had unfortunate experiences with profile documents where cached values were being returned. So Chris’s technique was extremely useful, because I could define the UNID, so be able to access the document quickly and reliably using getDocumentByUNID(). I’ve used it a number of times recently to access “profile” documents.
However, this week I encountered a bit of a conflict in XPages between this technique and the File Download control. If you manipulate the UNID and have a File Download control, as soon as there are attachments it throws a NullPointerException. The stack trace points to com.ibm.xsp.model.domino.DominoDocument$AttachmentValueHolder. After a host of investigation I tracked down a post with the same issue for file downloads, albeit not in XPages, but in JSF. After more testing, if the document had a natural UNID, the attachments showed fine. But if I removed the attachments, manipulated the UNID and added an attachment, it threw the NullPointerException. If I understand the post and the functionality correctly, the attachments are referenced via some internal reference that is broken when you change the UNID. It sounds like one of those issues that developers never anticipate (been there, done that).
This is definitely the case for Domino 8.5.2, but given the cause, I expect it would also be the case for prior versions of Domino. I don’t know if it’s something that can be overcome in the Domino code. But in the meantime, developers should be aware of it.
Two suggestions:
1. Set the UNID and upload the file(s) in separate transactions. For example, set the event that launches the profile editor to create – and save – the document if it doesn’t already exist, then redirect to it. I suspect that, if the new UNID is already set by the time the attachment is uploaded, the behavior will be as desired.
2. If that doesn’t work, add a layer of indirection. Create an attachment holder document, store its Domino-generated UNID in an item on the profile, then store and display the files using a data source linked to that UNID. You still get the advantage of being able to rapidly access the data, because you never have to query an index to locate the document, but the note actually storing the attachments hasn’t had its UNID manipulated. I’ve been meaning to blog about some cool stuff you can do by taking this approach to the extreme, but it’s rather a meaty topic, and spare time has been at a premium lately. 🙂
Thanks Tim. I had tried option 1, but no joy – the Profile is created when in the initial load, so I’m setting the correct UNID when the application is initialised, then using the same UNID as the documentId parameter of the datasource, setting ignoreRequestParams to true.
I thought of 2, but instead I’m just using a traditional document and doing a db.search on the form. Again, the UNID is set in an application scoped managed bean, so the performance hit shouldn’t be too bad.
Still thinking about the Logic-Driven UNIDs for user profile documents.