I have following xhtml document:
<h:body>
<ui:composition template="templates/layout.xhtml">
<ui:define name="content">
<c:if test="#{sessionBean.userCode > 0}">
<h:form id="findStudentForm">
<p:outputPanel id="resultsPanel">
<c:if test="#{studentsBean.student != null}">
<h2><h:outputText value="#{studentsBean.student.fullName}"/></h2>
<h3>Personal data</h3>
. . .
<p align="center">
<p:commandButton value="Search students" update="@form">
<f:setPropertyActionListener value="#{null}"
target="#{studentsBean.student}"/>
</p:commandButton>
</p>
</c:if>
<c:if test="#{studentsBean.student == null}">
<h2>Student search</h2>
. . .
<p align="justify">
First name
<h:inputText value="#{studentsBean.pattern}"/>
<p:commandButton value="Поиск" update="resultsPanel"/>
</p>
<p:dataTable id="resultsTable" var="student"
value="#{studentsBean.studentsList}"
widgetVar="studentsTable" emptyMessage="No records found">
. . .
</p:column>
<p:column headerText="Actions">
<p:commandButton value="Details" update="@form">
<f:setPropertyActionListener value="#{student}"
target="#{studentsBean.student}"/>
</p:commandButton>
</p:column>
</p:dataTable>
</c:if>
</p:outputPanel>
</h:form>
</c:if>
<c:if test="#{sessionBean.userCode == 0}">
<ui:include src="templates/include/error.xhtml"/>
</c:if>
</ui:define>
</ui:composition>
</h:body>
Also I have following Managed Bean (StudentsBean): . . .
@Named(value = "studentsBean")
@RequestScoped
public class StudentsBean {
@Inject
SessionBean session;
private Student student = null;
private String pattern = "";
private String groupName = "";
@Inject
private StudentInterface studentProvider;
. . .
public String getPattern() {
return pattern;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
public List<Student> getStudentsList() {
List<Student> result = new ArrayList<Student>();
if (studentProvider != null) {
try {
result = studentProvider.findStudents(pattern);
} catch (StudentException e) {
session.printError(e.getMessage());
}
}
return result;
}
. . .
And finally, I have a class StudentsProvider:
public class StudentProvider implements StudentInterface {
private Connection connection = null;
. . .
@Override
public List<Student> findStudents(String pattern) throws StudentException {
List<Student> result = new ArrayList<Student>();
String addon = "";
if (pattern.trim().isEmpty()) {
addon = "TOP 10 ";
}
try {
PreparedStatement statement = connection.prepareStatement(
"SELECT " + addon + "st_pcode, gr_Name, st_FullName "
+ "FROM students, groups WHERE (st_grcode = gr_pcode) AND (st_FullName LIKE ?) "
+ "ORDER BY gr_Name, st_FullName;", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
statement.setString(1, pattern + "%");
ResultSet rs = statement.executeQuery();
while (rs.next()) {
result.add(getStudent(rs.getString("st_pcode")));
}
rs.close();
statement.close();
} catch (Exception e) {
throw new StudentException("Error reading list: " + e.getMessage());
}
return result;
}
public StudentProvider() throws StudentException {
try {
ConnectionProvider provider = new ConnectionProvider();
connection = provider.getConnection();
} catch (ConnectionException e) {
throw new StudentException("Connect error: " + e.getMessage());
}
}
@Override
public void finalize() throws Throwable {
connection.close();
super.finalize();
}
}
If variable "pattern" an empty string, PreparedStatement returns 10 "first" records. But if the "pattern" has a content - PreparedStatement finds some records. During debug, seems like PreparedStatement works well and returns result set, but no records shows in the re"sultsTable". In additional, I found, that while updating process method
studentProvider.findStudent(pattern)
calling many times. I think, that number of method calls depends of number of records in the "resultsTable".
Before injection, with hard linked objects everything works fine. What's wrong?
By the way, I can't understand one thing. Say, I have a button
<p:commandButton value="Details" update="@form">
<f:setPropertyActionListener value="#{student}"
target="#{studentsBean.student}"/>
</p:commandButton>
in the each record of "resultsTable" (see xhtml listing before for more details). I found, that this button sometimes doesn't work. If resultsTable is empty at the beginning - button doesn't work, but if resultsTable is NOT empty - button work. So how can I make button always working?