Commenting System in XPages - xpages

I'm trying to implement a simple comment system in XPages. I have come across examples that create response documents from an existing document. The issue I'm having is when I open a new XPage and want to add a comment but I don't have an existing document because it hasn't been saved yet.
Is there a way I can create comments (response documents) on an unsaved document somehow? Or is there a different way to implement a comment system that doesn't use response documents?
Thanks for any tips.

If this is XPages then don't use a response document. Use a manual key of some sort. I prefer #Unique style keys - some people use UNIDS.
There's little to no value in using pure response document in XPages applications.
Patrick asks the key question. How can you have a "child" document if you don't first save the "parent" document.
Now of course you can save the parent and the child at the same time.

A response document need the unid of the main document for creation. If the main document is not saved you get the following exception.
Unable to create new document
NotesException: Invalid universal id
I don't know an other way to handle this problem.
Why don't you want to save the main document?

How can someone comment on something that does not exist?
I would need more details but you need to save the document. Perhaps you can move it into a different category like a draft view or something till it is ready for production?

Related

Invalid UniversalID when document has been copied

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 :)

I Need to prevent saved conflict in xpage

Scenario :- I opened the same document in different browsers(users). One user modified and saved the document. another user also modifying the same document which creates saved conflicts. for this I googled and found the link and tried.
http://dontpanic82.blogspot.in/2010/01/xpages-custom-control-that-can-help.html
(Thanks to Mr Tommy).
I included this custom control in another custom control(Form) at the end of Cc.
I am getting currentDocument not found in before render response event. I have my data source name document which is defined for full page not for panel.
Document handle is not getting in Before render response event?
Please help to me to solve this. or is there any other way to prevent saved conflicts?
Have a look at the concurrencyMode property of the document datasource.
You can for instance set it to fail in order for the document save to stop (fail) if a save conflict occurs. If you have (or add) a message control to your xpage, a save conflict error message will then appear.
If you isn't building for XPinc you could use my Document locker project on openntf.org
Document Locker on openntf.org
It works like this, when a user opens a document a< lock is added to an application scope bean. And when the user exits the document this lock is removed. if another user tried to enter the document at the same time they will be redirected to readmode.
Also, check the section in Mastering XPages 2nd Edition about document locking. That gives thorough examples for enabling the in-built Domino document locking.

What is the $$FormScript_0 field in Document Properties in LotusScript used for?

I've searched all over to find any information I can about this field. I have some emails that are being generated by one of my applications that crash notes each time you attempt to open them. If I compare the Document properties of one of these emails to a normal email, I find that there are many of these fields: $$$FormScript_0, $$$FormScript, $$FormScript_0, $$FormScript, etc.
Anyone know why these fields are generated and what purpose they serve? Just trying to rule them out as a cause of the crashed Notes.
MJ
I believe those items mean that the form is stored in the document. Some code on that form is crashing the client.

How to set Limit Number of Documents in a Form Library

I have a form library and want to limit the number documents added to it. I want the library to have only one item in it. Let me know if there is some easiest way to do it. The documents are added via infopath form.
There is no out of the box way for this. why do you want to have such limitation ?
If you really need to do this, you can impose this via event handler. But there are questions:
What will happen to new documents being added - Will they be deleted , moved somewhere ?

How to handle entity creation/editing in a master-detail

I'm wondering what strategies people are using to handle the creation and editing of an entity in a master-detail setup. (Our app is an internet-enabled desktop app.)
Here's how we currently handle this: a form is created in a popup for the entity that needs to be edited, which we give a copy of the object. When the user clicks the "Cancel" button, we close the window and ignore the object completely. When the user clicks the "OK" button, the master view is notified and receives the edited entity. It then copies the properties of the modified entity into the original entity using originalEntity.copyFrom(modifiedEntity). In case we want to create a new entity, we pass an empty entity to the popup which the user can then edit as if it was an existing entity. The master view needs to decide whether to "insert" or "update" the entities it receives into the collection it manages.
I have some questions and observations on the above workflow:
who should handle the creation of the copy of the entity? (master or detail)
we use copyFrom() to prevent having to replace entities in a collection which could cause references to break. Is there a better way to do this? (implementing copyFrom() can be tricky)
new entities receive an id of -1 (which the server tier/hibernate uses to differentiate between an insert or an update). This could potentially cause problems when looking up (cached) entities by id before they are saved. Should we use a temporary unique id for each new entity instead?
Can anyone share tips & tricks or experiences? Thanks!
Edit: I know there is no absolute wrong or right answer to this question, so I'm just looking for people to share thoughts and pros/cons on the way they handle master/details situations.
There are a number of ways you could alter this approach. Keep in mind that no solution can really be "wrong" per se. It all depends on the details of your situation. Here's one way to skin the cat.
who should handle the creation of the copy of the entity? (master or detail)
I see the master as an in-memory list representation of a subset of persisted entities. I would allow the master to handle any changes to its list. The list itself could be a custom collection. Use an ItemChanged event to fire a notification to the master that an item has been updated and needs to be persisted. Fire a NewItem event to notify the master of an insert.
we use copyFrom() to prevent having to replace entities in a collection which could cause references to break. Is there a better way to do this? (implementing copyFrom() can be tricky)
Instead of using copyFrom(), I would pass the existing reference to the details popup. If you're using an enumerable collection to store the master list, you can pass the object returned from list[index] to the details window. The reference itself will be altered so there's no need to use any kind of Replace method on the list. When OK is pressed, fire that ItemChanged event. You can even pass the index so it knows which object to update.
new entities receive an id of -1 (which the server tier/hibernate uses to differentiate between an insert or an update). This could potentially cause problems when looking up (cached) entities by id before they are saved. Should we use a temporary unique id for each new entity instead?
Are changes not immediately persisted? Use a Hibernate Session with the Unit of Work pattern to determine what's being inserted and what's being updated. There are more examples of Unit of Work out there. You might have to check out some blog posts by the .NET community if there's not much on the Java end. The concept is the same animal either way.
Hope this helps!
The CSLA library can help with this situation a lot.
However, if you want to self implement :
You have a master object, the master object contains a list of child objects.
The detail form can edit a child object directly. Since everything is reference types, the master object is automatically updated.
The issue is knowing that the master object is dirty, and therefore should be persisted to your database or whatnot.
CSLA handles this with an IsDirty() property. In the master object you would query each child object to see if it is dirty, and if so persist everything (as well as tracking if the master object itself is dirty)
You can also handle this is the INotifyPropertyChanged interface.
As for some of your other questions :
You want to separate your logic. The entity can handle storage of its own properties, and integrity rules for itself, but logic for how different object interact with each other should be separate. Look into patterns such as MVC or MVP.
In this case, creation of a new child object should either be in the master object, or should be in a separate business logic object that creates the child and then adds it to the parent.
For IDs, using GUIDs as the ID can save you quite a bit of problems, because then you don't have to talk to the database to determine a correct ID. You can keep a flag on the object for if it is new or not (and therefore should be inserted or updated).
Again, CSLA handles all of this for you, but does have quite a bit of overhead.
regarding undo on cancel : CSLA has n-level undo implemented, but if you are trying to do it by hand, I would either use your CopyFrom function, or refresh the object's data from the persistance layer on cancel (re-fetch).
i just implemented such a model.but not using NH, i am using my own code to persist objects in Oracle Db.
i have used the master detail concept in the same web form.
like i have master entity grid and on detail action command i open a penal just below the clicked master record row.
On Detail Add mode, i just populate an empty entity whose id were generated in negative numbers by a static field.and on Save Detail button i saved that entity in the details list of the Master Record in Asp.NET Session.
On Detail Edit,View i populated the Detail Panel with selected Detail through ajax calls using Jquery and appended that penal just below the clicked row.
On Save Button i persisted the Master Session (containing list of Details) in database.
and i worked good for me as if multiple details a master need to fill.
also if you like you can use Jquery Modal to Popup that Panel instead of appending below the row.
Hope it helps :)
Thanks,

Resources