Invalid UniversalID when document has been copied - xpages

I have a strange problem: I want to access documents in a different database (same server). My approach is very close to this one discussed here: http://www-10.lotus.com/ldd/nd85forum.nsf/DateAllFlatWeb/517ef6249d5b9fa6852575cc00503786?OpenDocument
I have only 3 docs in the source database. 2 are created directly, one is copied from another database (these are just test document). We have a generic view that lists thos entries from a view, calcs the links in a form like this:
http://localhost/database.nsf/xpMBK.xsp?action=openDocument&db=dominotest%2Ftest%2Fulcbs%21%21projects%2FFKIE%2FEinsMuB.nsf&view=AMBKEinsAll&documentId=781F14A98A699548C1257C3200316BAC
As you can see we are using an Xpage in the current database and place parameters that point the Xpage to open the document to the source database (notation is server!!database here), a view (this is the one to which I want to return) and finally the unid of the source document.
Now the strange one:
I cannot open the copied document, receiving the
NotesException: Invalid universal id
lotus.domino.local.Database.getDocumentByUNID(Unknown Source)
error.
Even better: if I copy a document that works within the same database (the current one) this document can also not opened anymore!
What's this and can you give me a hint to solve this?
Thanks in advance!

If, by "copied", you mean either manually copied and pasted into the target database or programmatically duplicated via copyToDatabase(), the new copy of the document will be assigned a new UNID; it is not guaranteed to have the same UNID as the original did (and, in my experience, it's rare that it preserves the original). If you're duplicating the document programmatically, be sure to check its new UNID afterward and use that ID in your URL calculation instead.

I've had a problem very similar to this in the past, and the answer turned out to be that I wasn't opening the NSF file that I thought I was opening. I was using NotesDatabase.OpenByReplicaID, and there were two replicas of the database on the server, with different sets of documents. In that situation, Notes gets to pick one of the two replicas -- you have no control over it. The replica that was actually opening contained some of documents corresponding the the UNIDs that I was trying to access, but some of them really were not there and therefore the getDocumentByUNID() method was correct in throwing the "Invalid universal id" error. This was really, really hard to debug.
After I figured it out and removed the second replica from my server, the first thing I did (after testing and confirming the problem went away) was to write an agent that scans a server for duplicate replica IDs.

The UNID:S in a Domino database when it's copied to the database thru copyToDatabase is done like this.
One part of the UNID comes from the database one part is document unique. So if you copy a document from one database to another the document could get the same unid each time. If the unique combination doesn't have a valid document with that combination in the database, the document will get the same UNID everytime. In other cases the document will get a new Id.
More information can be found here
UNID and copytodatabase

Thank you guys for your ideas!
But I was completely wrong #facepalm
The problem was: a colleague coded a bean to access the other database and I didn't noticed that the config document pointed to a replica on another server, so when I copied the document within my database on my local server it was fairly clear that the xpage could not find the copied one - as it resided on the other machine.
Thank you anyway :)

Related

Lotus Notes documents - Gets corrupt & Field Info Tab is empty

I have a notes database and recently we are having an issue across random documents. Users gets error "The linked document cannot be found in the view" when they try to open a document from a view. I am not sure how to reproduce this issue.
I tried the below options to reproduce it, but no luck:
Attaching a document link to one of the Rich text field and deleting the link's target.
Attaching a file as a link and deleting the file in the target.
I am not seeing any pattern with the documents having the issue. The documents accessed few days ago, which was not accessed for more than 2 years also becomes corrupt like this.
Other details:
The Field info tab in Document properties dialog box is empty
There is no scheduled agent running overnight affecting this documents
No change was done to the database recently
We recently migrated to Notes 11.0 from 9.0
Since we have a daily backup of the database, we restore the document from one of the restored copy in which it was working fine.
A guess: did you try re-indexing the view? Shift-F9?
It could also be in the form, or even the view.
What if ...
you open the same document from a different view?
you remove some, many or all fields from the form, do you still see the error?
I think those documents have actually been deleted, and two things make me think that:
You say in a comment that rebuilding the view makes the documents disappear. I'd expect this only if the documents no longer exist.
I have in the past had LotusScript code doing view lookups which produced documents that I knew to be deleted, but the NotesDocument.IsDeleted property was False and the NotesDocument.Items property was Empty (i.e. no fields in the document). This is consistent with your saying the Field info tab is empty.
I'd check if any user action or code could delete documents. You say there are no scheduled agents, but maybe some user action could run code which deletes documents, or some users with the Delete privilege in the database ACL could be directly deleting documents using the Delete key on the keyboard.
Also check the database properties -> Info tab -> User Detail. This should show if there are recent deletions, but the record is probably limited to the last week or less.

How to prevent Lotus Notes from saving a document created by a DXL Import?

I followed this link enabling me to setup a hotspot in a richtext field - works like charm.
http://ozinisle.blogspot.de/2010/11/lotusscript-code-to-append-hotspot-to.html
Only problem is, as the user(s) usually do(es) not have deletion rights, the document created by the import stays stored in the database. In LotusScript e.g. I can create a new temporary document and work with it, and if I'm not saving it, it just disappears at the end of the function.
Is there a similar way or parameter for DXL import which allows me to just drop the document after I got my rtitem?
Alternatively, can someone point out to me if it is possible to create only the temporary richtext item in/on a document I created as tempdoc via LotusScript?
My search on the web did not get any results and my tries to reduce the linked function always resulted in the error 4518 (which is described in the help document of "DXLImporter"); if I read the help right, the DXLImporter only supports the db as valid output (thus expecting documents being created via DXL).
I don't see a way to import DXL without creating a document.
The easiest solution is to create the temporary document in users "cache.ndk". The user has definitely the right to delete documents there. So, you'd replace the line "Set db = session.CurrentDatabase" in code you linked to with
Set db = session.Getdatabase("", "cache.ndk", false)
The rest of the code would stay the same.
As an alternative, use the more classic approach running an agent on server to delete the temporary document. Create an agent which deletes the document, set property "Run on behalf of" to someone who is allowed to delete documents in database and call the agent from your script with
agent.RunOnServer(noteID)

Fields not calculating in Lotus Notes

Using Lotus Notes designer I have created a form and added a field on that form that does a #DBColumn look up. The form then is viewed through the web browser and everything worked great.
I proceed to add another document to the database using that form, now the original documents still render in the browser fine but the new document doesn't return anything to the field.
I tried removing the #DBColumn look up and just displaying text but nothing I just get 0.
The weird thing is if I rename the field to something diferent everything works perfectly but then if I rename the field back, broken, no calculation.
Does anyone know why this is? It has happened to me with various fields through out my application. I originally thought maybe it was a reserved word thing but I now know that is not the case. I usually just rename the field and move on but there has to be an explanation. Is it a caching thing or what?
Thanks for the info!
You haven't mentioned the type of your fields Is it 'computed for display'? If you have computed for display fields in a form, and the documents already contain data stored in an item with the same name, then the computed formula is bypassed and the item value is displayed as-is.
Fields not calculating could be a caching issue. Try opening the form, edit mode, F9 to recalculate all fields.
If this does not help, close the form, press Ctrl+Shift+F9 to forcefully refresh all views in the DB (could take some time). Reopen your form, edit mode, F9. If the value shows up, try using the "nocache" parameter on your #DBColumn.
Depending on your application design, there could be a number of reasons for the problem. Perhaps the view used for lookup is not set to autorefresh or the server does not refresh often enough because of high load issues.

Document in Development server is not opening which were copied from production db.Lotus notes

I copy pasted some document from production server db to Dev server db , but when I tried to open any of these document then its giving error like ...The server with this database is no longer responding , should notes switch to a replica or another server ...whether old documents are opening fine in the Dev database.
Any suggestion appreciable...
Thank you.
The answer is going to be in the design of your application. You'll have to figure this one out on your own.
For example:
Does this record have computed or static fields (or formulas) pointing to the production server?
Does the form for the record use the 'unid' in one of the calculated fields (possibly as a key)? If so, you will get a broken key following the paste, since the last saved unid value would no longer match the actual doc unid.
Does your record have any other dependency records, that you also need to copy over?
Does your record have references (such as #DbLookups) to missing configuration records in your dev system (such as "keyword" lists or "system documents/profiles")?
Good luck

Creating Lotus Notes documents with specific created/modified/last accessed dates for testing

I'm currently writing an application that moves Notes documents between databases based on the amount of days that have elapsed from the creation/modified/last accessed dates. I would just like to get ideas on a simple and convenient way to create documents with specific dates, without having to change the time on the Domino server, so that I could test out my application.
The best way I found so far was to create a local replica and change the system clock to the date I want. Unfortunately there are problems associated with this method. It does not work on the modified date - I'm not sure how it is getting the modified date information when the location is set to Island (Disconnected) - and it also changes the modified and last accessed dates when the documents are replicated to the server replica.
Someone suggested trying to create a DXL of the document, modify the date time in the DXL file, then import it back into the database as a Notes document; but that does not work. It just takes on the date-time that it was created.
Can anyone offer any other suggestions?
You can set the created date for a document by setting the UNID (which is fundamentally a struct of timestamps, although the actual implementation has changed in recent versions). Accessed and modified times, though, would be unsettable from within the Notes/Domino environment, since the changes you make would be overwritten by the process of saving the changes. If you have a flair for adventure and a need to run with scissors, you could make the changes in the database file itself either programmatically from an external application, or manually with a hex editor. (Editing the binary will work -- folks have been using hex editors to clear the "hide design" flag safely for years. Keep in mind that signed docs will blow up badly, and that you need to ensure that local encryption is off for the database file.)
There's actually a very simple way to spoof the creation date/time: just add a field called $Created with whatever date/time you want. This is alluded to in the Notes C API header file nsfdata.h:
Time/dates associated with notes:
OID.Note Can be Timedate when the note was created
(but not guaranteed to be - look for $CREATED
item first for note creation time)
Obtained by NSFNoteGetInfo(_NOTE_OID) or
OID in SEARCH_MATCH.
Unfortunately, there's no analogous technique for spoofing the mod or access dates. At least none that's ever been documented, as far as I know.
I imagine given how dependent Lotus Notes is on timestamps (for replication, mainly), there isn't an API call that allows you to change the modified, created, or last access dates of a note. (More on the internals of Lotus Notes can be found here.)
I dug around the Notes C API documentation, and found only one mention on how to get/set information in the note's header, including the modified date. However, the documentation states that when you try to update that note (i.e. write it to disk), the last modified date will be overwritten with the date/time it is written to disk.
As an alternative, I would suggest creating your own set of date items within the documents that only you control, for example MyCreated, MyModified, and MyAccessed, and reference those in your code that moves documents based on dates. You would then be able to change these dates as easily as changing any other document item (via agents, forms, etc.)
For MyCreated, create a hidden calculated form field with the formula of #CREATED or #NOW. Set the type to computed when composed.
For MyModified, create a hidden calculated form field with the formula #NOW, and set the type to computed.
MyAccessed gets a bit tricky. If you can do without it, I suggest you live work with just the MyCreated and MyModified. If you need it, you should be able to manage it by setting a field value within the QueryOpen or PostOpen events. Problems occur if your users have only read access to a document - the code to update the MyAccessed field won't be able to store that value.
Hope this helps!

Resources