i have made jsf 2 webpage using primefaces 3.5 UI , so the webpage are worikng but my dataTable give empaty rows value , it should give me the values that's returned from database query .
note , i have tested the database query and it's working fine , but i think there is problem in sending this data to HTML beans .
my full code :
#ManagedBean
#SessionScoped
public class TableBean implements Serializable {
private static final long serialVersionUID = 1L;
public int model() throws ClassNotFoundException, ReflectiveOperationException, Exception{
try {
// i'm sure the following query return acutal data !
Dbconnection NewConnect = new Dbconnection();
Connection con = NewConnect.MakeConnect();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(" select student_id , teacher_id , apssent_date , interval_id , Day_id from Apsent where class_id = 1" ) ;
int StudentID ;
int ClassID ;
while(rs.next()){
StudentID = rs.getInt(1);
ClassID = rs.getInt(2);
return StudentID ; // or 0 or any value but the web page still give empaty rows value in data grid
}
}
catch (SQLException e){
}
return 0000;
}
my full html code :
<h:form>
<p:dataTable var="car" value="#{tableBean}">
<p:column headerText="Model">
<h:outputText value="#{model.StudentID}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{model.StudentID}" />
</p:column>
<p:column headerText="Manufacturer">
<h:outputText value="#{model.StudentID}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{model.StudentID}" />
</p:column>
</p:dataTable>
Well. As I see you totally missunderstand implementation.
Your bean as a model should have private properties i.e.
private List<Object> list;
private int someInteger.
and public accessors to them i.e.:
public setList(List<Object> list){
this.list = list;
}
public getList(){
return list;
}
then you can add some code to get method like this:
public getSomeInteger(){
return myObjectService.findAll(); //myObjectService.findAll() return result of some DB query.
}
then your xhtml datatable should look like:
<p:dataTable var="obj" value="#{yourBean.list}">
<p:column headerText="Model">
<h:outputText value="#{obj.property1}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{obj.property2}" />
</p:column>
<p:column headerText="Manufacturer">
<h:outputText value="#{obj.property3}" />
</p:column>
</p:dataTable>
For better understand JSF read some tutorials:
Mkyong or BalusC
Related
This question already has answers here:
What is a stack trace, and how can I use it to debug my application errors?
(7 answers)
JSF Controller, Service and DAO
(2 answers)
Closed 2 years ago.
I have small web application where the user should book movies. I created JSF pages and this way I display a list of movies available in the database:
<ui:composition template="/template.xhtml">
<ui:define name="title">
<h:outputText value="#{bundleMovie.ListMovieTitle}"></h:outputText>
</ui:define>
<ui:define name="body">
<h:form styleClass="jsfcrud_list_form">
<h:panelGroup id="messagePanel" layout="block">
<h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
</h:panelGroup>
<h:outputText escape="false" value="#{bundleMovie.ListMovieEmpty}" rendered="#{movieController.items.rowCount == 0}"/>
<h:panelGroup rendered="#{movieController.items.rowCount > 0}">
<h:outputText value="#{movieController.pagination.pageFirstItem + 1}..#{movieController.pagination.pageLastItem + 1}/#{movieController.pagination.itemsCount}"/>
<h:commandLink action="#{movieController.previous}" value="#{bundleMovie.Previous} #{movieController.pagination.pageSize}" rendered="#{movieController.pagination.hasPreviousPage}"/>
<h:commandLink action="#{movieController.next}" value="#{bundleMovie.Next} #{movieController.pagination.pageSize}" rendered="#{movieController.pagination.hasNextPage}"/>
<h:dataTable value="#{movieController.items}" var="item" border="0" cellpadding="2" cellspacing="0" rowClasses="jsfcrud_odd_row,jsfcrud_even_row" rules="all" style="border:solid 1px">
<h:column>
<f:facet name="header">
<h:outputText value="#{bundleMovie.ListMovieTitle_movieId}"/>
</f:facet>
<h:outputText value="#{item.movieId}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{bundleMovie.ListMovieTitle_movieName}"/>
</f:facet>
<h:outputText value="#{item.movieName}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{bundleMovie.ListMovieTitle_movieGenre}"/>
</f:facet>
<h:outputText value="#{item.movieGenre}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{bundleMovie.ListMovieTitle_movieRating}"/>
</f:facet>
<h:outputText value="#{item.movieRating}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{bundleMovie.ListMovieTitle_movieDate}"/>
</f:facet>
<h:outputText value="#{item.movieDate}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value=" "/>
</f:facet>
<h:commandLink action="#{movieController.bookAMovie(movie)}" value="Book" />
</h:column>
</h:dataTable>
</h:panelGroup>
<br />
<h:link outcome="/faces/adminIndex.jsp" value="Return to home page"/>
<br />
<br />
</h:form>
</ui:define>
</ui:composition>
As you can see, method <h:commandLink action="#{movieController.bookAMovie(movie)}" value="Book" /> should save the user selection in the new table, that table is bookedmovie while the data from the table is displayed to the user movie.
Method is:
public int bookAMovie(Movie movie) throws ClassNotFoundException {
String INSERT_USERS_SQL = "INSERT INTO bookedmovie"
+ " (bookedmoviename, bookedmoviegenre, bookedmovierating) VALUES "
+ " (?, ?, ?);";
int result = 0;
Class.forName("com.mysql.jdbc.Driver");
try (Connection connection = DriverManager
.getConnection("jdbc:mysql://localhost:3306/cs230projekat?useSSL=false", "root", "");
// Step 2:Create a statement using connection object
PreparedStatement preparedStatement = connection.prepareStatement(INSERT_USERS_SQL)) {
preparedStatement.setString(1, movie.getMovieName());
preparedStatement.setString(2, movie.getMovieGenre());
preparedStatement.setDouble(3, movie.getMovieRating());
System.out.println(preparedStatement);
// Step 3: Execute the query or update query
result = preparedStatement.executeUpdate();
} catch (SQLException e) {
// process sql exception
printSQLException(e);
}
return result;
}
I dont know how to fix this. It doesn't have to be this way, if anyone can help in any way, it suits me. Only that the user is shown movies from the database, that the user can select one movie and that his selection is stored in a new table.
Regarding Java code, below code is working fine.
I am able to run it.
Just make sure, you had added appropriate library of MySQL in your project also Make sure UserName/Password should be correct.Right now you had provided empty password.
As you didn't provided any error stack. I can't able to direct comment on that.
class Sample3 {
public static void main(String[] args) throws ClassNotFoundException {
bookAMovie(Movie.builder().movieGenre("Comic").movieRating(8).movieName("Movie1").build());
}
public static int bookAMovie(Movie movie) throws ClassNotFoundException {
String INSERT_USERS_SQL = "INSERT INTO bookedmovie"
+ " (bookedmoviename, bookedmoviegenre, bookedmovierating) VALUES "
+ " (?, ?, ?);";
int result = 0;
Class.forName("com.mysql.jdbc.Driver");
try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/sample?useSSL=false", "root", "PASSWORD");
// Step 2:Create a statement using connection object
PreparedStatement preparedStatement = connection.prepareStatement(INSERT_USERS_SQL)) {
preparedStatement.setString(1, movie.getMovieName());
preparedStatement.setString(2, movie.getMovieGenre());
preparedStatement.setDouble(3, movie.getMovieRating());
System.out.println(preparedStatement);
// Step 3: Execute the query or update query
result = preparedStatement.executeUpdate();
Statement statement=connection.createStatement();
ResultSet resultSet=statement.executeQuery("SELECT * FROM sample.bookedmovie");
List<Map<String, String>> mapList = getList(resultSet);
System.out.println(mapList);
} catch (SQLException e) {
// process sql exception
e.printStackTrace();
}
return result;
}
public static List<Map<String, String>> getList(ResultSet resultSet) throws SQLException {
List<Map<String, String>> mapList = new ArrayList<>();
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int columnNumber = resultSetMetaData.getColumnCount();
while (resultSet.next()) {
Map<String, String> map = new HashMap<>();
int count = 1;
while (count <= columnNumber) {
String columnName = resultSetMetaData.getColumnName(count);
map.put(columnName, resultSet.getString(columnName));
count++;
}
mapList.add(map);
}
return mapList;
}
}
#Data
#Builder
class Movie {
public String movieName;
public String movieGenre;
public double movieRating;
}
Here i had attached success screenshot from Java run and same record has been inserted in MySQL as well.enter image description here
MySQL
I have this table:
<h:form>
<p:dataTable id="books" value="#{ordersBean.userOrders}" var="book" selection="#{ordersBean.selectedBook}">
<p:column>
<f:facet name="header">Order ID</f:facet>
<h:outputText value="#{book[0]}"/>
</p:column>
<p:column>
<f:facet name="header">Title</f:facet>
<h:outputText value="#{book[1]}"/>
</p:column>
<p:column>
<f:facet name="header"></f:facet>
<p:commandButton id="selectRowBtn" value="select" action="#{ordersBean.showSelectedBook}"/>
</p:column>
</p:dataTable>
</h:form>
I want when i click on each select button, it's row information assigned to selectedBook property and displays it in showSelectedBook() method:
Here is the ordersBean:
private Book selectedBook = new Book();
public Book getSelectedBook() {
return selectedBook;
}
public void setSelectedBook(Book selectedBook) {
this.selectedBook = selectedBook;
}
public void showSelectedBook() {
System.out.println("In selected Book(), book: " + getSelectedBook());
}
But result is this:
In selected Book(), book: null
Should be something like this:
XML code:
<p:commandButton id="selectRowBtn" value="select"
action="#{ordersBean.showSelectedBook}">
<f:param name="bookId" value="#{book[0]}" />
</p:commandButton>
Java bean method:
public void showSelectedBook() {
Map<String,String> params =
FacesContext.getExternalContext().getRequestParameterMap();
int bookId = Integer.valueOf(params.get("bookId"));
for(Book book : bookList){
if(book.bookId == bookId){
selectedBook = book;
break;
}
}
System.out.println("In selected Book(), book: " + getSelectedBook());
}
Beside, you must have knowledge about the patterns for sending parameters to the actions, refer below link.
http://www.mkyong.com/jsf2/4-ways-to-pass-parameter-from-jsf-page-to-backing-bean/
If you want to show the selected book you have to set selectionMode="single" and there's no need to put a commandButton in each row, just specify only one commandButton in the footer facet like this:
<f:facet name="footer">
<p:commandButton id="selectRowBtn" value="select" action="#{ordersBean.showSelectedBook}"/>
</f:facet>
And your main problem here is that you are setting a new Book() to your selectedBook variable, so a null value to your selectedBook , this declaration:
private Book selectedBook = new Book();
Should be :
private Book selectedBook;
You don't have to instantiate a new Book() in your selectedBook.
Take a look at the second Example in this Showcase, to see how it works.
better solution and without select button :
Xml code:
<p:dataTable id="ListBook"
value="#{ordersBean.bookList}"
selection="#{ordersBean.selectedBook}" var="book"
rowKey="#{book.id}" selectionMode="single">
<p:ajax event="rowSelect"
listener="#{ordersBean.onRowSelectDataTable()}"
update="ListBook" />
..... <columns> ..
</p:datatable>
Java bean:
private Book selectedBook=new Book();
private boolean headerButtonsDisabled=true;
//add a List object for all books (bookList) with getter and setter
public boolean isHeaderButtonsDisabled() {
return headerButtonsDisabled;
}
public void setHeaderButtonsDisabled(boolean headerButtonsDisabled) {
this.headerButtonsDisabled = headerButtonsDisabled;
}
public void onRowSelectDataTable() {
this.setHeaderButtonsDisabled(false);
}
public Book getSelectedBook() {
return selectedBook;
}
public void setSelectedBook(Book selectedBook) {
this.selectedBook = selectedBook;
}
I'm using PrimeFaces 4.0 and Netbeans 6.9.1. I followed primefaces demo here:
DataTable Single Selection
Everything working fine expect button view. Here is my code:
Customer_list.xhtml
<p:growl id="msgs" showDetail="true" />
<h:form id="formTable">
<p:dataTable styleClass="table" id="customers" var="customer" value="#{customerBean.customer}">
<p:column>
<f:facet name="header">First Name</f:facet>
#{customer.firstName}
</p:column>
<p:column>
<f:facet name="header">Last Name</f:facet>
#{customer.lastName}
</p:column>
<p:column>
<f:facet name="header">Email</f:facet>
#{customer.email}
</p:column>
<p:column>
<f:facet name="header">DOB</f:facet>
#{customer.dob}
</p:column>
<p:column style="width:4%">
<p:commandButton id="selectButton" update=":formCreate" oncomplete="dialogCustomerCreate.show()" icon="ui-icon-search" title="Update">
<f:setPropertyActionListener value="#{customer}" target="#{customerBean.selectedCustomer}" />
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
<h:form id="formCreate">
<p:dialog header="Create New Customer" widgetVar="dialogCustomerCreate" resizable="false" id="dlgCustomerCreate"
showEffect="fade" hideEffect="explode" modal="true">
<h:panelGrid id="display" columns="2" cellpadding="4" style="margin:0 auto;">
<h:outputText value="First Name:" />
<h:outputText value="#{customerBean.selectedCustomer.firstName}" style="font-weight:bold"/>
<h:outputText value="Last Name:" />
<h:outputText value="#{customerBean.selectedCustomer.lastName}" style="font-weight:bold"/>
<h:outputText value="Email:" />
<h:outputText value="#{customerBean.selectedCustomer.email}" style="font-weight:bold"/>
<h:outputText value="DOB:" />
<h:outputText value="#{customerBean.selectedCustomer.dob}" style="font-weight:bold"/>
</h:panelGrid>
</p:dialog>
</h:form>
customerBean.java
public class customerBean {
private List<Customer> customer;
private Customer selectedCustomer;
/** Creates a new instance of customerBean */
public customerBean() {
customer = new ArrayList<Customer>();
}
public List<Customer> getCustomer() {
CustomersDao cust_dao = new CustomersDao();
customer = cust_dao.findAll();
return customer;
}
public Customer getSelectedCustomer() {
return selectedCustomer;
}
public void setSelectedCustomer(Customer selectedCustomer) {
this.selectedCustomer = selectedCustomer;
}
}
CustomersDao.java
public class CustomersDao {
public List<Customer> findAll(){
List<Customer> list_cust = null;
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
String sql = "FROM Customer";
try{
session.beginTransaction();
list_cust = session.createQuery(sql).list();
session.beginTransaction().commit();
}catch(Exception e){
session.beginTransaction().rollback();
}
return list_cust;
}
}
Hope anyone suggest me what wrong in my code. It takes me 2 days to solve it. Thanks for reading!
You need to have a converter for your Customer class:
#FacesConverter(forClass = Customer.class)
public class CustomerConverter implements Converter {
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value != null && !value.equals("") && !value.equals("0")) {
//find and return object from DAO
} else {
return null;
}
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
//return object id as string
}
}
1) Try removing your <h:form/>, since you're not submitting any information in that dialog;
2) Try to change your <p:commandButton update=""/> to update=":display";
3) Add process="#form" to your <p:commandButton/>;
4) If that works, i don't think you need that <h:form/>.
you did not mention the correct id for displaying popup dialog at commandButton attribute update.
<p:commandButton id="selectButton" update=":formCreate:display" oncomplete="dialogCustomerCreate.show()" icon="ui-icon-search" title="Update">
<f:setPropertyActionListener value="#{customer}" target="#{customerBean.selectedCustomer}" />
</p:commandButton>
I got dataTable defined as:
<p:dataTable var="account" value="#{customerBean.accounts}"
id="accounts" lazy="true">
<p:column>
<f:facet name="header">
<h:outputText value="#{msg['editCustomerForm.accountNumbers.header']}" />
</f:facet>
<h:outputText value="#{account.accountNumber}" />
</p:column>
</p:dataTable>
And accounts are loaded in this method (called in #PostConstruct method)
private void initAccounts() {
accounts = new CustomLazyDataModel<Account>() {
#Override
public List<Account> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
return accountService.getAccountsForCustomer(customerModel.getCustomer(), first, pageSize);
}
};
accounts.setPageSize(10);
}
CustomLazyDataModel is there only because of this bug: http://code.google.com/p/primefaces/issues/detail?id=1544 (see comment #23)
But when page is rendered, component says "No records found."
SQL in hibernate log executed on the server returns 1 row and when i use dataList insted of dataTable result is corect (1 row is rendered).
<p:dataList value="#{customerBean.accounts}" var="account"
id="accounts-old" rows="10"
type="none" lazy="true">
<f:facet name="header">
<h:outputText value="#{msg['editCustomerForm.accountNumbers.header']}" />
</f:facet>
<h:outputText value="#{account.accountNumber}" />
</p:dataList>
When using <h:dataTable> records are there also. So what is the problem with <p:dataTable>?
Only thing that was missing on the component was rows parameter.
<p:dataTable var="account" value="#{customerBean.accounts}" id="accounts" lazy="true" rows="10" paginatorAlwaysVisible="false" >
Now records are rendered.
I'm trying to filter a dataTable using Primefaces much like this example. (In a web browser) I type the text I want to filter by, it works once but when I remove the text I've written the result stays the same when it should go back to it's original state.
So it works once and then won't respond. (I can remove or re-type the filter text I've written but it does not affect the table anymore)
Sorry about the weird attribute names in the code, bear with me. :)
xhtml-page:
<h:form>
<p:dataTable var="aggr" value="#{aggregationManagedBean.logiskAdressatModel}"
widgetVar="aggrTable"
emptyMessage="No aggr found with given criteria">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Filter:" />
<p:inputText id="globalFilter" onkeyup="aggrTable.filter()" />
</p:outputPanel>
</f:facet>
<p:column filterBy="#{aggr.name}">
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{aggr.name}" />
</p:column>
</p:dataTable>
</h:form>
backing bean:
#ManagedBean
#SessionScoped
public class AggregationManagedBean {
private List<LogiskAdressat> logiskaAdressater;
private DataModel<LogiskAdressat> logiskAdressatModel;
public AggregationManagedBean() {
logiskaAdressater = getLogiskaAdressater();
logiskAdressatModel = new ListDataModel<LogiskAdressat>(logiskaAdressater);
}
private static List<LogiskAdressat> getLogiskaAdressater(){
List<LogiskAdressat> logiskaAdressater = new ArrayList<LogiskAdressat>();
logiskaAdressater.add(new LogiskAdressat("01 addr_id 01", "Joe"));
logiskaAdressater.add(new LogiskAdressat("02 addr_id 02", "John"));
logiskaAdressater.add(new LogiskAdressat("03 addr_id 03", "Jake"));
return logiskaAdressater;
}
public DataModel<LogiskAdressat> getLogiskAdressatModel() {
return logiskAdressatModel;
}
public void setLogiskAdressatModel(DataModel<LogiskAdressat> adressatModel) {
this.setLogiskAdressatModel(adressatModel);
}
}
Is LogiskAdressat Serializable?
If not, then try making it Serializable -
public class LogiskAdressat implements Serializable {
//....