JSF:绝对需要将昂贵的业务逻辑放在访问器方法中。 如何避免称这个昂贵的BL倍数时间

这是我的困境,我知道在JSF中访问器方法会多次调用,因此我知道不要在访问器方法中放置昂贵的业务逻辑(如DB访问)。 如果我必须将业务逻辑放入我的访问器中该怎么办? 在这种情况下我该怎么办? 以下是我的困境的高层次布局。 (Mojarra 2.1,GF 3.1)

  #{item1.name} says: #{item1.comment}   #{item2.name} replies: #{item2.comment}     @ManagedBean @ViewScoped public void myBean(){ private List comments; @EJB private MyEJB myEJB; @PostConstruct public void init(){ comments = myEJB.getAllComments(); } //getters and setters for List comments public List handleReplies(Comment comment){ //Return a List of replies of the comment return myEJB.getRepliesFromComment(comment); } } 

如您所见, inner dataTable接受outer dataTable的item以生成其List。 有没有办法以某种方式停止handleReplies()被多次调用,因为这个访问器方法访问DB。

如何使用HashMap创建视图范围的缓存?

就像是:

 private Map> replies = new HashMap>(); public List handleReplies(Comment comment){ if (!replies.containsKey(comment)) { replies.put(comment, myEJB.getRepliesFromComment(comment)); } return replies.get(comment); } 

这样,视图范围的bean存储先前的请求结果,并在请求已经完成时返回它们。 如果没有,则发出请求。 最后,没有重复的请求!

您也可以让JPA执行延迟加载和缓存作业(使用适当的二级缓存)。

假设您的Comment实体看起来像这样

 @Entity @NamedQuery(name="Comment.list", query="SELECT c FROM Comment c WHERE c.parent IS NULL") public class Comment implements Serializable { @ManyToOne(optional=false) private Comment parent; @OneToMany(mappedBy="parent", fetch=LAZY, cascade=ALL); private List children; // ... } 

您可以使用#{comment.children}来(懒惰地)将孩子放在