开发者

JSF 2 Lifecycle

I have this code for BookModel.java:

@Entity
@Table(name = "BOOK")
@NamedNativeQuery(name = "BookModel.findBookTitle", query = "SELECT @rownum:=@rownum+1 'no', m.title, m.author开发者_运维技巧, REPLACE(SUBSTRING_INDEX(m.content, ' ', 30), '<br>', ' '), m.viewed, m.hashid FROM book m, (SELECT @rownum:=0) r WHERE m.title like 'a%'")
public class BookModel implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MY_SEQ_GEN")
    @Column(name = "id", unique = true, nullable = false)
    private Long id;

    @NotNull
    @Size(min = 1, max = 255)
    @Column(name = "title")
    private String title;

    @NotNull
    @Size(min = 1, max = 255)
    @Column(name = "author")
    private String author;
}   

And BookService.java for the business layer:

@Stateless
public class BookService
{
    @SuppressWarnings("unchecked")
    public List<BookModel> getBook() {
       Query query = entityManager.createNamedQuery("BookModel.findBookTitle");
       List<BookModel> result = query.getResultList();
       return result;
    }
 }

And BookBean.java for the presentation layer:

@ManagedBean(name = "BookBean")
@RequestScoped
public class BookBean implements Serializable
{
    @EJB
    private BookService bookService;
    private DataModel<BookModel> book;

    public DataModel<BookModel> getBook() {
       return book;
    }
}   

And the page book.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.prime.com.tr/ui">
    <p:dataTable id="bookList" value="#{BookBean.book}" var="book">
    ...
    </p:dataTable> 
 </html>

My question is: How can I restrict the method getBook() in BookBean to be executed only once instead of six times - presumably for each phase of JSF lifecycle. Has anyone else come across this before? Please help. Have been stuck on this for the last day without any success.


That's not possible. It should usually not harm. Getters are solely there to provide access points to bean properties, not to do some business jobs.

If you did call the @EJBs getBook() method inside that managed bean method like follows

public DataModel<BookModel> getBook() {
   return new ListDataModel<BookModel>(bookService.getBook());
}

then this is indeed going to be expensive as it would call the DB that much times as the getter is called. You would like to do the job in the bean's constructor or @PostConstruct instead.

@PostConstruct
public void init() {
    book = new ListDataModel<BookModel>(bookService.getBook());
}

See also:

  • Why JSF calls getters multiple times?

Unrelated to the concrete problem, the method name getBook() and variable name book is not really self-documenting since it actually contains more than one book. I'd use getBooks() and books instead.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜