Make JSF wait for database - jsf

I have a JSF page to submit form values to a database. When clicking a button, values are submitted to my ManagedBeans and written to a database via JPA. Then the updated values from the database should be displayed in a dataTable at the same page.
The problem is: The database is too slow, so JSF seems to render the page before those are in the database (thus only rendering the older ones already there). How can I make JSF wait for the database to finish writing the values? I can figure out how to get the current phase of a lifecylce, but not how to stop it...

The problem is: The database is too slow, so JSF seems to render the page before those are in the database (thus only rendering the older ones already there). How can I make JSF wait for the database to finish writing the values?
This makes honestly no sense. JSF just does the job you told it to do in the bean's action method. Apparently you are not reloading the list from the DB after the persist. Perhaps you are referring to that the updated item is only visible when you refresh the page so that a new GET request is fired which reloads the data from the DB.
The canonical approach is to just reload the data from the DB immediately after the save.
public void save() {
someService.save(some); // Save item in DB.
list = someService.list(); // Reload list from DB.
}

Related

Persisting a DataTable state through views in Primefaces

First of all: not native english speaker here, so sorry if I may sound a little confusing sometimes.
I'm looking for a way to persist a DataTable (that shows a query result list) state when I navigate through different views in my application (so it's not an Ajax call), in other words: I need to render a new page with a DataTable exactly as it was in the previous view. First thing you should know about this is that I have a way to transport objects through my views using ELFlash.getFlash().put(param, obj), so my problem is not recovering objects.
I was able to make the DataTable open with all the previous result list with no problems... BUT it has a paginator and I was supposed to get to the second view not only with the query results but also opened in the same page that it was before.
I already tried to keep the current page number in an object and put a code to change the paginator to that page in the post construct, but it didn't work:
DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent(":form:dataTable");
String javaScript = "PF('widgetVarName').getPaginator().setPage(" + this.pageNumber + ")";
RequestContext.getCurrentInstance().execute(javaScript);
The saddest thing here is that It didn't work in post construct and the DataTable doesn't open in the right page, but if I call this code in another button, after the page is already rendered, it works.
Do you guys have any ideia?

Xpages document changing document mode?

I have a strange thing occurring; as usual, I can't post code, unfortunately, so I'm describing the problem in case anyone can suggest a possible cause.
I have an xpage with a custom control included on it; the custom control handles document locking and changing to edit/read-only modes via links. The document locking is done by setting an applicationScope variable based on the UNID. To make it more friendly for other users on the system, I run a function periodically on the page to check whether the document is locked or not and update a link/label/tooltips appropriately (e.g. if locked by another user, then the "Edit" button is disabled; when the lock is released, it's re-enabled). This is done by calling an "xagent" through a standard, simple dojo-based ajax call.
For some reason, the behavior of the system gets erratic after 45 seconds to a minute. I'm checking the lock status every ten seconds or so, so it's not happening with the first call. I'm displaying a list of records associated with the document; each record is a row in a repeat. When I first go into edit mode, the controls are all displayed as they should be, i.e. editable. If the user changes a particular value with a combobox, it updates the whole row with a partial refresh. When things get erratic, I noticed that the row starts refreshing in read-only mode, which suggests to me that the document is changing edit mode. The only time I knowingly change edit mode is if a "Cancel" or "Save" button is pressed. (The locking mechanism itself doesn't have anything to do with the edit mode.)
It certainly seems like the ajax call I'm making is at the root of this. But I've stripped the xagent and the client-side code down to practically nothing, and it's still happening. I can't see what would be causing this behavior. Can anyone hazard a guess? Thanks....
Maybe check if the server log file has warnings like:
WARNING CLFAD####W: State data not available for /page because no control tree was found in the cache.
If you're seeing those warnings, it could be that the server can no longer find the current XPage page instance in the cache. In that case the page will revert to the initial state, like when the page was first opened. That might be why the document goes to read-only mode.
The session cache of server-side page instances only holds 4 pages when xsp.persistence.mode=basic, or it holds 16 instances when xsp.persistence.mode=file or fileex.
If you load 4 xagent page instances, then that will fill the cache, and it will no longer be able to find the page instance for the current XPage you are viewing. So the XPage will stop performing server-side actions, and partial refresh will always show the initial state of that area of the page.
To avoid that problem, in the xagent page you can set viewState="nostate" on the xp:view tag, so that page instances are not saved for the xagent page, as described here:
https://tobysamples.wordpress.com/2014/12/11/no-state-no-problem/
Or else you can create and reuse one page instance for the xagent, so only one is created. That is, on the first call to the XAgent, have the xagent return the $$viewid value for the xagent page instance (#{javascript:view.getUniqueViewId()}), and then in subsequent requests to the xagent use that $$viewid in the request, to restore the existing xagent page instance instead of creating new instances that will fill the cache. So the subsequent xagent requests will be like so:
/myApp.nsf/xagent1.xsp?$$viewid=!aaaaaaaa!
It's hard to troubleshoot without code, but here are a few thoughts:
How are you checking document locking? Via a client-side JavaScript AJAX call or an XPages partial refresh? If the latter, what is the refresh area? If the former, what is the refresh area you're passing and the return HTML? Does it always occur when you're in edit mode on a row and the check happens, or independently of that? The key thing to check here is what the check for locking is doing - is it checking the server and returning a message outside the repeat, or checking the server and returning HTML that overwrites what's currently on the browser with defaults, e.g. the document mode as read mode.
What network activity is happening between the browser and the server and when? Is something else overwriting the HTML for the row, so resetting the row to read mode.
It's unlikely to be random, the key is going to be identifying the reproduceable steps to identify a common scenario/scenarios and cause.
EDIT
Following on from your additional info, is there a rendered property on the Edit link? If that calculates to false in earlier JSF lifecycle phases, the eventHandler is not available to be triggered during the Invoke Application phase. Because the eventHandler also includes the refreshId, there is no refreshId and refreshMode, so it defaults to a full refresh with no SSJS running. See this blog post for clarification http://www.intec.co.uk/view-isrenderingphase-and-buttons/.

XPage not syncing properly with backend data on partial refresh

I have an XPage that displays fields in a document. I also have the ability to pop out a new window that displays those same fields. I'm implementing a document locking scheme so that the two instances can't cause conflicts (and this is how I'm testing it).
A problem I've run into is that when the user edits the document in the pop out and saves it, a partial refresh of the panel containing those same fields in the original page doesn't show the updated data.
The save in the pop out was successful, and I can see in the Notes client that the document does indeed have the new value, but the original page simply won't show the new value. A complete page refresh using the reload button in the browser works, but I'd like to trigger this programmatically and as quickly as possible, hence the partial refresh.
Does anyone know what is going wrong? Is the NotesXspDocument in the original page getting out of sync with the backend document? I read about document1.getDocument(true), but that doesn't seem to do anything.
(As usual, I can't supply source code unfortunately....)
Once the NotesXspDocument is loaded with the XPage, a partial refresh does not update the xspDoc from the back-end DB, but from the in-memory DataSource.
You will need to refresh the XPage:
Reload the url from browser or in ssjs with a context.reloadPage()

JSF: poll server, render button/link, so user can refresh view

The most popular page in my JSF/PrimeFaces web app is a page with p:dataTable with data spanning date ranges (and yes, FROM and TO p:calendar are used for filtering the data along with p:inputText and p:autoComplete components, when/as necessary).
I would like to poll for changes in the data listed in the dataTable for selected dates (date range). I would like to render an Update or Refresh commandButton/Link ONLY IF data has changed for the current view for any/every user.
When a given user makes an update to data, I would like to inform other users in any/all other sessions that this data was changed, and if user(s) is/are viewing that data on a page/view via dataTable (or detailed view), then user can click Refresh button to see the update, but the Refresh button/link is only rendered via AJAX via polling. Of course, I want this 'action' to be initiated or some flag (or POJO may be more appropriate) to be stored on server ('List dataThatWasUpdated'), and polling would check this 'per' user (like the polling-Notifications implementation that I already have in place, which is working perfectly). During polling, this list will be scanned, and if user is viewing any of the data that is in the List, then Boolean will be set on another managedBean to render the commandButton/Link. This List would be set to null after each polling.
In the near or distant future, after I migrate to CDI, I will do this via CDI and server-sent-events (SSE) via HTML (and Java EE CDI, of course), but for now I am considering using or adding p:poll to give user the opportunity/option to refresh the view (since data has been updated by another user).
Please confirm my thoughts/design and/or advise. Thanks.
p:poll is fine but a WebSocket/Comet Framework could be nicer (and not really complicated to add). And as you are using Primefaces, you could use Atmosphere (http://atmosphere.java.net). They had a p:push to achieve such a goal.

how to distinguish a jsf action or direct url link invoked the page

I have a situation, I have a session bean with list, this list I show in html data table. When the user hits the url from browser or normal href, I have to show all records. There is provision to search for the data also, where I have to show the filtered list. Now after a user has made the search, the list contains filtered records and after doing this he leaves the page to some other, and now if the user hits the url or uses the menu to come back to this page, since I have this list in session bean, I still have the filtered list.
Since there is no default action in JSF 1.1 or 2.0 preRenderView concept, its difficult to clear the list and get non filtered data(all results) again. Even tricks in getList() method fail to accomplish the task.
I have planned to use phase listener, as when a user reaches a page via href or url hit in browser, invoke application phase does not happen. I can toggle boolean variable in my session bean and in getList() I can perform some trick to check it was url,href hit or by command button.
Hope I have made myself clear. In short I have to identify in my bean whether the request came directly from href,browser or an action. If search action filter records for data table if not keep list cache and keep showing it as long as search is not made.
Just guide me whether I am doing things in right way or thinking too much or can it be done in much more efficient way.
Thanks in advance.
Well platform is jsf 1.1 in weblogic portal 10.3 .....
JSF 1.x actions use by default POST method. Direct links/bookmarks/etc are by nature GET method. Since there's no ResponseStateManager#isPostback() or FacesContext#isPostback() in JSF 1.1, you have to determine the request method yourself:
HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
boolean postback = "POST".equalsIgnoreCase(request.getMethod());
Or check for a certain parameter in the request parameter map, but I can't tell from top of head which one you'd like to check. You've to determine it yourself.
boolean postback = facesContext.getExternalContext().getRequestParameterMap().containsKey(SOME_KEY);
If postback is true, then a JSF action is been invoked.

Resources