If I have a h:dataTable
in books.xhtml providing a list of records and I want to view a particular record, then add or edit that record, currently I have this:
<h:dataTable #{BookBean.books}" var="books">
<h:link outcome="bookview" value="#{books[1]}">
<f:param name="id" value="#{books[2]}" />
</h:link>
</h:dataTable>
I found out that I need to include <f:param>
in order to show the CSS status of clicked link; otherwise if I don't have <f:param>
, every time I clicked on a link rendered by h:link tags in the codes above, all links are changed to CSS clicked status.
Also, I read somewhere about the getrowdata()
but I haven't been able to get it work. Is this a better alternative to using <f:param>
?
I have tried the getrowdata()
method in my BookBean class as followed:
private DataModel<BookModel> books;
private BookModel currentBook;
public String view()
{
currentBook = books.getRowData();
return "bookview";
}
and in bookview.xhtml I have this:
<h:dataTable value="#{BookBean.view}" var="item">
... // render content here
<h:dataTable>
but I get an error about the property not found. Sorry for asking this question but I still don't understand yet some of the powerful features of JSF 2. Can some expert who understand the usage of h:link
and getrowdata
please explain to me in layman terms or perhaps with some basic code example. Thank you.
UPDATE: Changed classes based on @BalusC suggestions below. BookModel class is:
@Entity
public class BookModel implements Serializable
{
private Long id;
private String title;
private String author;
// getters and setters here
}
The BookService class looks like this:
@Stateless
public class BookService
{
@PersistenceContext(unitName = "persistentUnit")
protected EntityManager entityManager;
public BookModel create() {
return new BookModel();
}
public void delete(BookModel bookModel) {
bookModel = entityManager.merge(bookModel);
entityManager.remove(bookModel);
}
public BookModel update(BookModel bookModel) {
return entityManager.merge(bookModel);
}
public BookModel find(Long id) {
return entityManager.find(BookModel.class, id);
}
}
The BookBean class is:
@ManagedBean(name = "bookBean")
@RequestScoped
public class BookBean implements Serializable
{
@EJB
private BookService bookService;
@ManagedProperty(value = "#{param.id}")
private Long id;
private DataModel<BookModel> books;
private BookModel currentBook;
@PostConstruct
public void init() {
currentBook = bookService.find(id);
}
public BookModel getCurrentBook() {
return currentBook;
}
public void setCurrentBook(BookModel currentBook) {
this.currentBook = currentBook;
}
}
Running the BookBean class above caused this error: java.lang.IllegalStateException: WEB9031: WebappClassLoader unable to load resource [org.apache.openjpa.util.LongId], because it has not yet been started, or was already stopped
. This is where I'm stuck at the moment.
FYI: My dev environment is Glassfish 3.1, Apache OpenJPA 2.1 and JSF 2.1.0 (that comes bundled with Glassfish)