Efficient JSF Pagination - jsf-2

Whats the most efficient way of doing pagination in JSF 2.0 app?
I use Primefaces datatable and it is intelligent enough to perform
pagination by itself with no coding at all.
<p:dataTable var="car" value="#{carBean.cars}" paginator="true" rows="10">
<!-- Multiple columns here-->
</p:dataTable>
The thing that I see, is that I need to place my bean to session scoped or greater.
#ManagedBean
#SessionScoped
public class CarBean{
public List<Car> getCars(){
//return data from DB
}
}
I wanted to know is there another efficient way on how to perform this?
I used EJB/JPA at the backend by the way. Would like to know any links or tutorials
to learn more about this.
Thanks.

You need to use LazyDataModel in order to have only the rows in memory which the client actually needs to see. See also the example in PrimeFaces showcase. This does pagination at DB level which is what you ultimately want.
RichFaces supports by the way the same in flavor of ArrangableDataModel, here's the RichFaces showcase example.

In a production app, we've used a lazy datamodel to deal with 700000 records in db. I'd suggest using M3 which has fixes on lazy datatable cases.

I have found that the built in pagination feature of the Primefaces data table is one of the best features and did a good amount of load testing on it, bringing in recordsets with over 30,000 Hibernate entities and found the performance to be lackluster. This of course means that you will have 30,000 entities in session so I have the following in my web.xml to help by storing session on the server side.
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
This will reduce the size of the ViewState allowing request/response size to be greatly reduced however server side memory can suffer enormously by doing this.
Another potential option in some JSF implementations to help mitigate the size of ViewStat or session memory usage is compression. The following link describes a number of SUN RI and MyFaces JSF configuration parameters that can be set, some of which give the option of compression of the session state. http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Frweb_jsfengine.html
As far as learning more about how the Primefaces DataTable pagination feature works, why not go straight to the source? Primefaces is after all an open source project, so just look at the code and see what you can learn: http://code.google.com/p/primefaces/source/browse/#svn%2Fprimefaces

Important note depending on which version of Primefaces you are using. Starting with 3.0.M2 (I think) if you want to use the row select feature you must implement a SelectableDataModel. This breaks a lot of legacy code and there were a number of bitches about that.
Easiest thing to do is to create an inner class like this:
private MyDataModel dataModel = null;
public MyDataModel getDataModel() {
if (dataModel != null) return dataModel;
dataModel = new MyDataModel(some list);
return dataModel;
}
public static class MyDataModel extends ListDataModel<SomeRecord>
implements SelectableDataModel<SomeRecord> {
MyDataModel(List<SomeRecord> source) {
super(source);
}
etc.
Then the value attribute to p:dataTable becomes #{bean.dataModel}.
Good luck.

Related

Migrating RichFaces SerializableDataModel implementation to custom DataModel implementation

I have been tasked with migrating JSF 1.x with RichFaces 3.x on JSP to JSF 2.x on Facelets. The previous developer used RichFaces <rich:dataTable>. As data a bean was sent to the table. This bean was a SerializableDataModel which has a walk() method allowing you to easily traverse the data table using the visitor pattern. This also allowed the table to only load data needed using lazy loading. We have over 216k rows of data and all of them are loaded when the page loads or when you try to change pages to view the next set of rows.
I thus need to migrate this to JSF 2.x. I have never used JSF 2.x before and I am simply asking if anyone has ever experience this, how they solved it and if they can give me some resources to get started.
I can not share more as it is against my works policies.
<h:dataTable value="#{records}" var="record" rows="20"
class="table table-striped"
styleClass="dataTableRecords dataListTable" rowClasses="odd, even"
id="dataTableRecords" rendered="#{records.rowCount > 0}">
</h:dataTable>
#ManagedBean(name="records")
#RequestScoped
public class Records extends BseDataModel{...}
BseDataModel is what contained our walk method, it now extends DataModel
If you think you can help please let me know, I can give some more limited information, if you need it please ask.

#Named versus #Model - CDI vs/and ManagedBean

I was wondering about this article explaining the direct access of EJB from JSF : http://www.mastertheboss.com/cdi/context-dependency-injection-with-jboss-weld
I do understand, that with CDI you can inject and access every bean type, including entity beans from the far end of the layer tier.
However.
[Question 1]: Should I discard the #Model controller and only apply #Named to all the classes? This kind of abandons the approach of having JSF --> ManagedBean--> EJB --> EntityBean to JSF --> EJB --> EntityBean. I just have the feeling this extra ManagedBean is causing me an extra layer without not much benefit.
[Question 2]: In what cases would you still want to maintain that extra Controller layer?
thanks
I don't think that there is a universal answer. It depends on your controller, both are valid arquitectures.
The key is whether your controller requires services offered by the container.
For example if your controller should execute outside a transaction then justifies the extra layer.
However, always tend towards simplicity if you can. If your application is simple enough to have just the three layers then don't over complicate it.
As far as replacing #Model for #Named goes, #Model is just a shortcut for a #RequestScoped #Named bean. Only replace #Model for #Named if you want the bean to have some other scope.
The best way to get the most from the overall platform is to use CDI as your controller layer (receiving requests from the JSF based frontend) and delegating internally to EJBs or other CDI beans for business logic. I would not use JSF ManagedBeans as the concept is deprecated in Java EE 7, in favor of the CDI programming model.
The controller can be used to always convert data types, separating out your front end and back end models.
I think the equation should be:
JSF = View (.xhtml) + Controller (ManagedBean)
EJB = Model
There's no skipping to go directly from View to Model unless you're putting the whole back-end logic inside a ManagedBean, which is obviously not a good practice.

How do I store the last page visited on my Sitecore site and then display that when a user returns

Quite new to Sitecore, I am building a Sitecore web application with no authentication (anonymous). It's a large project with lots of hierarchical top, side menus.
When the user revisits the website, I need load the page that was last visited with menu item highlighted. Could someone please help me whether there's any Sitecore API that provides this and if not what would be the ideal solution i.e. store last visited page on client cookie?
An option I can see would be storing the last visited page on client cookie like you said, then build in a custom processor and put it in the
<httpRequestBegin>
pipeline in the web.config.
A custom processor needs to inherit from the HttpRequestProcessor class, and you'd need to override the Process method.
What I would suggest in this case is having your custom processor like this:
<processor type="Your.NameSpace.ClassName, Your.Assembly" />
<processor type="Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel" />
and have something like the following:
namespace Your.Namespace
{
public class ClassName : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
// Get cookie:
var cookievalue = WebUtil.GetCookieValue("cookiename");
WebUtil.Redirect(cookievalue);
}
}
}
Of course this suggest you'll store the URL of the last visited page in the cookie. You could also store the ID of the last visited item in the cookie of course, and get it's path from there.
I just came across this article, and as Holder mentions, it should be possible to get the information from DMS if you have it enabled and are using it:
Get last visited pages from a Sitecore DMS (OMS) Profile
As far as I know, there isn't anything in the default API that does this.
There might be something in Sitecore OMS, but I don't know much about OMS.
I think a cookie, might be the easiest and simplest way of doing this.

ASP.NET MVC: run code after view has rendered (close db transaction)

I am using ASP.NET MVC2 with NHibernate, but am facing an issue. All calls to the database via NHibernate should be inside a transaction, however code inside the view kicks off database calls in some instances. Thus there is a need to be able to commit the transaction after the view has rendered.
For example displaying a list of users and their user roles you might show the user role using this code: <%: Model.UserRole.Name %>
This will cause a hit on the database as the UserRole is loaded using a NHibernate proxy.
You can fetch the UserRole eagerly which circumvents the issue in this case, but there are cases where it is much faster to use lazy loading.
Anyway, is there a way to run code after the view has rendered?
Have you tried to use session-per-request pattern? It's a very natural way of handling NHibernate sessions in web environment.
There are many information available when you do a Google search on "NHibernate session per request", like this blog post.
Also, take a look at great Bill McCafferty's article NHibernate Best Practices. Although it's written for NHibernate 1.2, it has a wealth of information. While there, his S#arp Architecture also looks very cool :)
How about an action filter?
public class CleanUpAttribute: ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
//cleanup code here
}
}
Then you decorate your controllers with this attribute.

ASP.NET MVC Response Filter + OutputCache Attribute

I'm not sure if this is an ASP.NET MVC specific thing or ASP.NET in general but here's what's happening. I have an action filter that removes whitespace by the use of a response filter:
public class StripWhitespaceAttribute : ActionFilterAttribute
{
public StripWhitespaceAttribute ()
{
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
filterContext.HttpContext.Response.Filter = new WhitespaceFilter(filterContext.HttpContext.Response.Filter);
}
}
When used in conjunction with the OutputCache attribute, my calls to Response.WriteSubstitution for "donut hole caching" do not work. The first and second time the page loads the callback passed to WriteSubstitution get called, after that they are not called anymore until the output cache expires. I've noticed this with not just this particular filter but any filter used on Response.Filter... am I missing something?
I also forgot to mention I've tried this without the use of an MVC action filter attribute by attaching to the PostReleaseRequestState event in the global.asax and setting the Response.Filter value there... but still no luck.
This KB article may offer some insight into the root cause of this issue. While the filter 'breaks' caching in IIS6 it throws an error in IIS 7. This seems to be a design / test-time improvement at best.
UPDATE
Here's an official "answer" from MS Dev Support on this issue.
Question:
What is the alternative to response filtering in ASP.NET for modifying HTML rendered by another process when:
1. The other process cannot be modified
2. Post-cache substitution must be supported
Answer:
"Yes, you question is clear as blue sky and this is officially claimed to be not support. As Post-cache substitution would combine certain substitution chunks to the response bytes while response filtering expects to filter the raw bytes of the response(not modified). So the previously combined substitution chunks cannot be preserved anymore.
There is not an alternative from Microsoft so far."
AFAIK, the problem is that the action filters doesn't get executed if the request goes to the output cache. The AuthorizeAttribute works around this problem by calling some obscure Output Cache API. However, I don't think that is the best solution for what you're are trying to do.
You should be working with output cache, not around it. What you should be doing instead is making sure that the spaces are removed from the response before it gets stored in the output cache.
Update
It seems that attaching a filter, no matter what filter, disables the WriteSubstitution functionality as you suspect. I've tried following the trail in the HttpResponse class using reflector but I can't find any proof that confirms this suspicion. I think the answer lies within the HttpWriter class.
Another Update
It so happens that I'm currently reading the excellent book "Pro ASP.NET MVC Framework" by Steve Sanderson (buy it if you don't already have it). In chapter 10 he links to a post on his blog where he talks about partial output caching and the poor integration between the MVC framework and the output cache. I haven't tried the custom outputcache attribute in the post yet... I will try it out and let you know if it does anything to solve the problem.

Resources