Reputation: 6516
I've created article composite component which I use in almost every page. This CC loads data from database and insterts it in a view. To use this CC I need to only call <cc:article id="article-id"/>
so it's really simple to use. The problem is that I need to load data from database on every request so it is not the best solution. I want to optimize it but I don't know how. Before I will write whats ideas I've got to solve this problem lets see how most important parts of cc looks like:
This is CC
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" ...>
<h:body>
<cc:interface componentType="articleFacesComponent">
<cc:attribute name="articleId" required="true" />
<cc:attribute name="editable" type="boolean" default="false" required="false" />
<cc:attribute name="styleClass" default="article" required="false" />
</cc:interface>
<cc:implementation>
<h:outputStylesheet library="cc" name="js/article.css" />
<div class="#{cc.attrs.styleClass}">
...
<!-- here I load article from FacesComponent -->
<h:outputText value="#{cc.article.text}" escape="false" />
...
</div>
</cc:implementation>
</h:body>
</html>
This is FacesComponent used by cc
import entity.Article;
import javax.faces.component.FacesComponent;
import javax.faces.component.UINamingContainer;
import javax.persistence.EntityManager;
import service.DatabaseManager;
@FacesComponent("articleFacesComponent")
public class ArticleFacesComponent extends UINamingContainer {
private Article article;
private EntityManager em;
public Article getArticle() {
if (article==null) {
init();
}
return article;
}
private void init() {
em = DatabaseManager.getInstance().em();
Object idObj = getAttributes().get("articleId");
if (idObj != null) {
String id = String.valueOf(idObj);
if (id != null) {
article = em.find(Article.class, id);
if (article == null) {
article = new Article(id);
}
}
}
}
}
First of all I want to write what is the problem with this solution:
getArticle()
I need to call init()
every time because cc attributes are not visible in constructor.How it should work?
What ideas I've got so solve this problem?
List
. The pros of this solution is that I will load data from db only once but the cons are that I need to keep all articles in memory. Now I've got about 30 articles so it can work in that way but in the future there may be 300 or 3000 articles so it will waste memory.Upvotes: 1
Views: 248
Reputation: 1108632
As to the concrete question, the JSF utility library OmniFaces has an <o:cache>
component which allows you to cache the component's generated HTML output in the session or even the application scope on a specific key for a determined period. See also the showcase page.
Upvotes: 1