Populate table with nested Collections - jsf

I´m looking for a solution for my problem.
I have a table that needs to be like this.
--------------------------------------------------------------|
| | Title 3 |
Title 1 |Title 2|---------------------------------------------|
| | SubTitle 1 |SubTitle 2|SubTitle 3|SubTitle 4|
--------------------------------------------------------------|
| | | | | |
Val A1 | ValB1 | ValC1 | ValC1 | ValC1 | ValC1 |
| | | | | |
|-------|------------|----------|----------|----------|
| | | | | |
| ValB2 | ValC2 | ValC2 | ValC2 | ValC2 |
| | | | | |
--------------------------------------------------------------|
| | | | | |
| | | | | |
Val A2 | ValB3 | ValC3 | ValC3 | ValC3 | ValC3 |
| | | | | |
| | | | | |
----------------------------------------------------------------
My goal it´s to make a table appear like I did above.
I´m using JSF and Primefaces 4.0.
I have this struture of class.
Class Master {
private List<ClassA> classesA
// getter and setter
}
Class A {
private List<ClassB> classesB
// getter and setter and fields
}
Class B {
private List<ClassC> classesC
// getter and setter and fields
}
Class C {
// getter and setter and fields
}
So I tried to make with two datatables or using ui:repeat, but I don´t know what´s going to be the best choose. And the titles the owns like this.
Class A have title 1, Class B have title 2 and Class C have title 3 and subtitle 1,2,3 and 4.
Or use binding.
To be more easier to understand I put a picture about how I need to create the table.
Can someone help me?
Thanks

If you are sure that the object structure won't change in future then simple solution is to go for ui:repeat with nested tables, rowspan and colspan. But if the object structure often changes and you need to do it more than one time then go for custom component.If you need olap features then i suggest you to go for pivot4j or something similar.
update: see the xhtml below it creates the body of the table.
<table border="4" cellspacing="4" cellpadding="10">
<tr>
<th rowspan="2">A</th>
<th rowspan="2">B</th>
<th colspan="4">C</th>
</tr>
<tr>
<th>p1</th>
<th>p2</th>
<th>p3</th>
<th>p4</th>
</tr>
<ui:repeat var="classa" value="#{master.classesA}" varStatus="astat">
<ui:repeat var="classb" value="#{classa.classesB}" varStatus="bstat">
<ui:repeat value="#{classb.classesC}" var="classc" varStatus="cstat">
<tr>
<h:panelGroup rendered="#{bstat.index eq 0 and cstat.index eq 0}">
<td rowspan="#{classa.colSpan}" >
<h:outputText value="#{classa.property}" />
</td>
</h:panelGroup>
<h:panelGroup rendered="#{cstat.index eq 0}">
<td rowspan="#{classb.classesC.size()}">
<h:outputText value="#{classb.property}" />
</td>
</h:panelGroup>
<td>
<h:outputText value="#{classc.prop1}" />
</td>
<td>
<h:outputText value="#{classc.prop2}" />
</td>
<td>
<h:outputText value="#{classc.prop3}" />
</td>
<td>
<h:outputText value="#{classc.prop4}" />
</td>
</tr>
</ui:repeat>
</ui:repeat>
</ui:repeat>
</table>
and classes should look like this
public class A {
private List<B> classesB;
private String property;
public List<B> getClassesB() {
return classesB;
}
public void setClassesB(List<B> classesB) {
this.classesB = classesB;
}
public A(String pro) {
classesB= new ArrayList<B>();
property=pro;
}
public void addClassB(B b){
classesB.add(b);
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
public int getColSpan(){
int size=0;
for(B b : classesB){
size+=b.getClassesC().size();
}
return size;
}
}
public class B {
private List<C> classesC;
private String property;
public B(String pro) {
this.classesC = new ArrayList<C>();
this.property=pro;
}
public List<C> getClassesC() {
return classesC;
}
public void setClassesC(List<C> classesC) {
this.classesC = classesC;
}
public void addClassC(C c){
classesC.add(c);
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
}
public class C {
private String prop1;
private String prop2;
private String prop3;
private String prop4;
public C(String prop1, String prop2, String prop3, String prop4) {
this.prop1 = prop1;
this.prop2 = prop2;
this.prop3 = prop3;
this.prop4 = prop4;
}
public void setProp1(String prop1) {
this.prop1 = prop1;
}
public void setProp2(String prop2) {
this.prop2 = prop2;
}
public void setProp3(String prop3) {
this.prop3 = prop3;
}
public void setProp4(String prop4) {
this.prop4 = prop4;
}
public String getProp1() {
return prop1;
}
public String getProp2() {
return prop2;
}
public String getProp3() {
return prop3;
}
public String getProp4() {
return prop4;
}
}
Test data in Master class.
private List<A> classesA;
#PostConstruct
public void init() {
classesA = new ArrayList<A>();
A a1 = new A("a1");
A a2 = new A("a2");
classesA.add(a1);
classesA.add(a2);
B b11 = new B("b11");
B b12 = new B("b12");
B b21 = new B("b21");
a1.addClassB(b11);
a1.addClassB(b12);
a2.addClassB(b21);
C c111 = new C("a", "b", "c", "d");
C c112 = new C("d", "e", "f", "g");
C c121 = new C("g", "h", "i", "j");
C c211 = new C("k", "l", "m", "n");
C c212 = new C("o", "p", null, null);
b11.addClassC(c111);
b11.addClassC(c112);
b12.addClassC(c121);
b21.addClassC(c211);
b21.addClassC(c212);
}
public List<A> getClassesA() {
return classesA;
}
public void setClassesA(List<A> classesA) {
this.classesA = classesA;
}

You can use dataTable with subTable (and you can add columns in row if needed).

Related

display jsf 2D table

I want to display a 2D array in my view .xhtml, which contains the database column as rows, but I can not get a 2D array
my BD Table
training | experience | motivation
NA | B | AT
I want to display a data table as follows
| evaluation | comment
-------------------------------------------
training | A | ...
-------------------------------------------------- -----
experience | B | ....
You'll have to write some Java code in a managed bean like this:
public class SomethingSomethingDTO {
private final String subject;
private final String evaluation;
private final String comment;
public SomethingSomethingDTO(final String subject,
final String evaluation, final String comment) {
this.subject = subject;
this.evaluation = evaluation;
this.comment = comment;
}
public String getSubject() {
return subject;
}
public String getEvaluation() {
return evaluation;
}
public String getComment() {
return comment;
}
}
#PostConstruct // or some other event or command button action
public void initializeSomething() {
somethings = new ArrayList<>();
somethings.add(new SomethingSomethingDTO("training", "A", "..."));
somethings.add(new SomethingSomethingDTO("experiance", "B", "..."));
}
private List<SomethingSomethingDTO> somethings;
public List<SomethingSomethingDTO> getSomethings() {
return somethings;
}

Display table titles from nested list shows to much

I'm writing a blog, and I want to display from database dataTable with 2 columns, in one column I would like to have post title, and in other I want post content, but when I try to implement that in my page, the only result I get is that in post title column is displayed all post titles for every row. I would like to ask you, how could I achieve my goal.
Now i have
title1 title2 ... | content1
title1 title2 ... | content2
etc
but I would like to have
title 1| content1 <br>
title2 | content2 <br>
Here is my index.xhtml code to display dataTable
<h:dataTable value="#{postView.postList}"
var="k"
styleClass="table"
headerClass="tableHeader"
rowClasses="tableContent"
>
<h:column>
<h:dataTable value="#{postView.postList}" var="t">
<h:column>
#{t.title}
</h:column>
</h:dataTable>
</h:column>
<h:column>
#{k.postContent}
</h:column>
</h:dataTable>
Here is my controller
package ManagePost;
import Entities.Post;
import FacadeDAO.PostFacade;
import FacadeDAO.UserFacade;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
#Named
#ViewScoped
public class PostView implements Serializable {
#Inject
private PostFacade postDAO;
private List<Post> postList;
private String title;
private String content;
public PostView() {
}
public List<Post> getPostList() {
return postList;
}
public void setPostList(List<Post> postList) {
this.postList = postList;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
#PostConstruct
public void init() {
postList = postDAO.showAll();
}
public String validate() {
Post post = postDAO.checkIfExist(title);
if (post == null) {
Post newPost = new Post();
newPost.setTitle(title);
newPost.setPostContent(content);
try {
postDAO.add(newPost);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return "loginPage";
} else {
return null;
}
}
}
And the last, PostDao
public List<Post> showAll() {
List<Post> postList = new ArrayList<>();
List<Post> result = getEntityManager().createNamedQuery("Post.findAll", Post.class).getResultList();
postList.addAll(result);
return postList;
}
You are displaying all the titles in an embedded datatable. You should remove the nested datatable tag:
<h:dataTable value="#{postView.postList}"
var="k"
styleClass="table"
headerClass="tableHeader"
rowClasses="tableContent"
>
<h:column>
#{k.title}
</h:column>
<h:column>
#{k.postContent}
</h:column>
</h:dataTable>

Overriding/implementing getRowKey() and getRowData() methods, when there is a composite primary key which combines multiple columns as a row key

I have a table in MySQL database. Unfortunately, there is a composite primary key which is needed for JAAS authentication/authorization in GlassFish Server.
mysql> desc group_table;
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| user_group_id | varchar(176) | NO | PRI | NULL | |
| group_id | varchar(15) | NO | PRI | NULL | |
+---------------+--------------+------+-----+---------+-------+
2 rows in set (0.05 sec)
The table contains data in the following format.
mysql> select * from group_table;
+-------------------------+------------+
| user_group_id | group_id |
+-------------------------+------------+
| you123#gmail.com | ROLE_ADMIN |
| you123#gmail.com | ROLE_USER |
| you123#ymail.com | ROLE_USER |
| you123#hotmail.com | ROLE_USER |
| you123#yahoo.com | ROLE_USER |
+-------------------------+------------+
5 rows in set (0.00 sec)
A <p:dataTable> with rowKey works fine , when lazy is set to false.
<p:dataTable rowKey="#{row.groupTablePK.userGroupId} #{row.groupTablePK.groupId}">
...
</p:dataTable>
GroupTablePK is an #Embeddable class (JPA). The details about this class is not needed I presume.
When lazy is however, enabled on a <p:dataTable>, the getRowKey() and the getRowData() methods need to be implemented.
How can this be done, when there is a composite primary key which requires a combination of columns as a row key - a unique row identifier?
#Named
#ViewScoped
public class UserAuthorityManagedBean extends LazyDataModel<GroupTable> implements Serializable {
private static final long serialVersionUID = 1L;
#Override
public Object getRowKey(GroupTable groupTable) {
return groupTable != null ? groupTable.getGroupTablePK() : null;
}
#Override
public GroupTable getRowData(String rowKey) {
List<GroupTable> list = (List<GroupTable>) getWrappedData();
System.out.println("rowKey : " + rowKey);
}
#Override
public List<GroupTable> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) {
//... setRowCount(rowCount);
//... Return a List<GroupTable> from a business Service.
}
}
The above implementations are left incomplete.
When a row is selected in the <p:dataTable> with these implementations, the sout statement inside the getRowData() method displays the following.
Info: rowKey : entity.GroupTablePK[ userGroupId=you123#gmail.com
Info: rowKey : groupId=ROLE_USER ]
The getRowKey() method returns an instance of GroupTablePK but the getRowData() method only accepts a String type parameter. It is not an object representing the composite primary key (hereby GroupTablePK) so that it can be type-cast to an appropriate object type (GroupTablePK) and based on which an instance of GroupTable may be obtained from the given List<GroupTable> and get the getRowData() method to return that instance of GroupTable.
How to proceed further?
The question is purely based on the immediate previous question :
java.lang.UnsupportedOperationException: getRowData(String rowKey) must be implemented when basic rowKey algorithm is not used
EDIT:
I have hashcode() and equals() implementations in addition to toString() in GroupTablePK. The toString() method in GroupTablePK returns return "entity.GroupTablePK[ userGroupId=" + userGroupId + ", groupId=" + groupId + " ]"; but the getRowData() method is invoked twice, when a row in a <p:dataTable> is selected. It returns the string representation of GroupTablePK in two parts in two subsequent calls. In the first call, it returns entity.GroupTablePK[ userGroupId=aaa and then in the second call, it returns groupId=ROLE_USER ].
It should instead return entity.GroupTablePK[ userGroupId=aaa, groupId=ROLE_USER ] at once in a single call.
This kind of comparison groupTable.getGroupTablePK().toString().equals(rowKey) is therefore not possible which I was thinking about prior to this post. Such as,
#Override
public GroupTable getRowData(String rowKey) {
List<GroupTable> list = (List<GroupTable>) getWrappedData();
for (GroupTable groupTable : list) {
if (groupTable.getGroupTablePK().toString().equals(rowKey)) {
return groupTable;
}
}
return null;
}
EDIT 2:
The following is the shortest possible example removing the JPA noise to reproduce the problem.
Attempted alternatively on,
PrimeFaces 3.5
PrimeFaces 4.0
PrimeFaces 5.0
PrimeFaces 5.1
PrimeFaces 5.2
The behaviour remains stationary on all of these versions of PrimeFaces.
The managed bean:
#Named
#ViewScoped
public class CompositeRowKeyManagedBean extends LazyDataModel<GroupTable> implements Serializable {
private List<GroupTable> selectedValues; // Getter & setter.
private static final long serialVersionUID = 1L;
public CompositeRowKeyManagedBean() {}
private List<GroupTable> init() {
List<GroupTable> list = new ArrayList<GroupTable>();
GroupTablePK groupTablePK = new GroupTablePK("aaa", "ROLE_ADMIN");
GroupTable groupTable = new GroupTable(groupTablePK);
list.add(groupTable);
groupTablePK = new GroupTablePK("bbb", "ROLE_USER");
groupTable = new GroupTable(groupTablePK);
list.add(groupTable);
groupTablePK = new GroupTablePK("ccc", "ROLE_USER");
groupTable = new GroupTable(groupTablePK);
list.add(groupTable);
groupTablePK = new GroupTablePK("ddd", "ROLE_USER");
groupTable = new GroupTable(groupTablePK);
list.add(groupTable);
groupTablePK = new GroupTablePK("eee", "ROLE_USER");
groupTable = new GroupTable(groupTablePK);
list.add(groupTable);
return list;
}
#Override
public List<GroupTable> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
List<GroupTable> list = init();
setRowCount(list.size());
return list;
}
#Override
public Object getRowKey(GroupTable groupTable) {
return groupTable != null ? groupTable.getGroupTablePK() : null;
}
#Override
public GroupTable getRowData(String rowKey) {
List<GroupTable> list = (List<GroupTable>) getWrappedData();
System.out.println("rowKey : " + rowKey);
for (GroupTable groupTable : list) {
if (groupTable.getGroupTablePK().toString().equals(rowKey)) {
return groupTable;
}
}
return null;
}
public void onRowEdit(RowEditEvent event) {
GroupTablePK groupTablePK = ((GroupTable) event.getObject()).getGroupTablePK();
System.out.println("grouoId : " + groupTablePK.getGroupId() + " : userGroupId : " + groupTablePK.getUserGroupId());
}
}
The data table :
<p:dataTable var="row"
value="#{compositeRowKeyManagedBean}"
lazy="true"
editable="true"
selection="#{compositeRowKeyManagedBean.selectedValues}"
rows="50">
<p:column selectionMode="multiple"></p:column>
<p:ajax event="rowEdit" listener="#{compositeRowKeyManagedBean.onRowEdit}"/>
<p:column headerText="GroupId">
<h:outputText value="#{row.groupTablePK.userGroupId}"/>
</p:column>
<p:column headerText="UserGroupId">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{row.groupTablePK.groupId}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{row.groupTablePK.groupId}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Edit">
<p:rowEditor/>
</p:column>
</p:dataTable>
When a row is attempted to edit, the onRowEdit() method is invoked. The getRowData() is invoked twice and produces a split of the row key in two subsequent calls as said earlier.
These are two domain classes GroupTable and GroupTablePK.
public class GroupTable implements Serializable {
private static final long serialVersionUID = 1L;
protected GroupTablePK groupTablePK;
public GroupTable() {}
public GroupTable(GroupTablePK groupTablePK) {
this.groupTablePK = groupTablePK;
}
public GroupTable(String userGroupId, String groupId) {
this.groupTablePK = new GroupTablePK(userGroupId, groupId);
}
public GroupTablePK getGroupTablePK() {
return groupTablePK;
}
public void setGroupTablePK(GroupTablePK groupTablePK) {
this.groupTablePK = groupTablePK;
}
#Override
public int hashCode() {
int hash = 0;
hash += (groupTablePK != null ? groupTablePK.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
if (!(object instanceof GroupTable)) {
return false;
}
GroupTable other = (GroupTable) object;
if ((this.groupTablePK == null && other.groupTablePK != null) || (this.groupTablePK != null && !this.groupTablePK.equals(other.groupTablePK))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entity.GroupTable[ groupTablePK=" + groupTablePK + " ]";
}
}
public class GroupTablePK implements Serializable {
private String userGroupId;
private String groupId;
public GroupTablePK() {}
public GroupTablePK(String userGroupId, String groupId) {
this.userGroupId = userGroupId;
this.groupId = groupId;
}
public String getUserGroupId() {
return userGroupId;
}
public void setUserGroupId(String userGroupId) {
this.userGroupId = userGroupId;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
#Override
public int hashCode() {
int hash = 0;
hash += (userGroupId != null ? userGroupId.hashCode() : 0);
hash += (groupId != null ? groupId.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
if (!(object instanceof GroupTablePK)) {
return false;
}
GroupTablePK other = (GroupTablePK) object;
if ((this.userGroupId == null && other.userGroupId != null) || (this.userGroupId != null && !this.userGroupId.equals(other.userGroupId))) {
return false;
}
if ((this.groupId == null && other.groupId != null) || (this.groupId != null && !this.groupId.equals(other.groupId))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entity.GroupTablePK[ userGroupId=" + userGroupId + ", groupId=" + groupId + " ]";
}
}
I ran your MCVE (kudos to that!) and reproduced it. The rowkey appears to be interpreted as a commaseparated string in the client side to cover the case when multiple selection is needed. This will fail if the string representation of a single rowkey contains a comma, as in your case. The rowkey argument you got in getRowData() is clear evidence of it: they are the results when the original value is split on comma.
So, to solve this problem, you need to make sure that the getRowKey().toString() doesn't contain a comma anywhere. Better use a different separator character. E.g. an underscore.
#Override
public Object getRowKey(GroupTable groupTable) {
GroupTablePK pk = groupTable != null ? groupTable.getGroupTablePK() : null;
return pk != null ? pk.getUserGroupId() + "_" + pk.getGroupId() : null;
}
From reading your question I am guessing that the getRowKey() method must return something that is uniquely identifiable to a single row. It is understandable that the underlying JPA entity that represents your row has a composite key object which is fine. The problem I think that is for a Java object to use anything as a key in a Map type collection, the key object must overload and define a proper implementation for the equals and hashCode methods.
I suspect that Primefaces probably is using a Map of some kind to retrieve values based on a key. The String type is usually a good candidate for unique key of an object because Strings are immutable and have proper implementations of equals and hashCode. They make a good candidate for this so if you must pass a String to getRowData then you can always provide a method on that object that returns a unique string for that object. This might be for instance a base 64 representation of the hashCode implementation you provide for your row data object.
If String is not a required parameter then simply implement equals and hashCode for composite key object and use that directly as your key.

JSF property action listener target

I am starting out using JSF and I am trying to add a record to a database using the details entered into the form by the user. My XHTML page includes this form.
<h:form>
<table id ="addRecordTable">
<tr>
<td><h:outputText value="Enter Name: " /></td>
<td><h:inputText value="#{animal.name}" id="name" label="name" required="true" requiredMessage="Name is required.">
<f:validateLength minimum="2" maximum="15"></f:validateLength>
</h:inputText>
</td>
</tr>
<tr>
<td><h:outputText value="Enter Age: "/></td>
<td><h:inputText value="#{animal.age}" id="age" label="age" required="true" requiredMessage="Age is required."></h:inputText></td>
</tr>
<tr>
<td><h:outputText value="Enter Breed : " /></td>
<td><h:inputText value="#{animal.breed}" id="breed" label="breed" required="true" requiredMessage="Breed is required.">
<f:validateLength minimum="2" maximum="15"></f:validateLength>
</h:inputText>
</td>
</tr>
<tr>
<td></td>
<td><h:commandButton value="Add" action="#{animalBean.add}">
<f:setPropertyActionListener target="#{animalBean.animal.age}" value="#{animal.age}" />
<f:setPropertyActionListener target="#{animalBean.animal.name}" value="#{animal.name}" />
<f:setPropertyActionListener target="#{animalBean.animal.breed}" value="#{animal.breed}" />
</h:commandButton></td>
</tr>
</table>
</h:form>
I also have these java Managed Bean classes:
import javax.faces.bean.ManagedBean;
#ManagedBean
public class Animal {
private int id;
private String breed;
private int age;
private String name;
public Animal(int id, int age, String breed, String name) {
this.breed = breed;
this.age = age;
this.id = id;
this.name = name;
}
public Animal()
{
this.breed= "";
this.age = 0;
this.id = 0;
this.name= "";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void setBreed(String breed) {
this.breed = breed;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getBreed() {
return breed;
}
public int getAge() {
return age;
}
#Override
public String toString()
{
return "Animal [id=" + id + ", breed=" + breed + ", age=" + age
+ ", name=" + name + "]";
}
}
and....
import javax.faces.bean.ManagedBean;
#ManagedBean
public class AnimalBean
{
protected Animal animal = new Animal();
public List <Animal> getAnimals() {
List <Animal> animals = new ArrayList <Animal> ();
ResultSet rs = null;
PreparedStatement pst = null;
Connection con = null;
String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\\Users\\lwilson\\Animals.accdb";
try {
con = DriverManager.getConnection(url);
System.out.println("Connection completed (Select All).");
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
String stm = "SELECT Breed,Age,Name, ID FROM Animals";
try {
pst = con.prepareStatement(stm);
pst.executeQuery();
rs = pst.getResultSet();
while (rs.next()) {
int age = rs.getInt("Age");
String breed = rs.getString("Breed");
String name= rs.getString("Name");
int id = rs.getInt("ID");
Animal a1 = new Animal(id,age, breed, name);
animals.add(a1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return animals;
}
public void add() {
File db = new File("C:\\Users\\lwilson\\Animals.accdb");
if (!db.exists()) {
System.out.println("file not found");
}
PreparedStatement ps = null;
Connection con = null;
String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\\Users\\lwilson\\Animals.accdb";
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con = DriverManager.getConnection(url, "", "");
String sql = "INSERT INTO Animals(Age, Breed, Name) VALUES(?,?,?)";
ps = con.prepareStatement(sql);
ps.setInt(1, animal.getAge());
ps.setString(2, animal.getBreed());
ps.setString(3, animal.getName());
ps.executeUpdate();
System.out.println("Data Added Successfully Into Database");
} catch (Exception e) {
System.out.println(e);
System.out.println("exception here");
}
}
My issue is that in the setPropertyActionListener, the target does not set the Animal object field to the value from the form. I receive an error saying that the target cannot access the field of the created animal object. These fields are then in turn passed into the add() method.
Any help would be appreciated. Thanks.
You can inject your Animal class object into your AnimalBean class using #ManagedProperty annotation as
#ManagedBean
public class AnimalBean {
#ManagedProperty
protected Animal animal;
// getter and setter
// Here your other methods
}
In this case no need to use
<f:setPropertyActionListener target="#{animalBean.animal.age}" value="#{animal.age}" />
<f:setPropertyActionListener target="#{animalBean.animal.name}" value="#{animal.name}" />
<f:setPropertyActionListener target="#{animalBean.animal.breed}" value="#{animal.breed}" />
You will get your property value using Animal class getter and setter.
It should looks like this:
1) Getter and setter for animal object in managed bean class
2) Refering in form to animal object by #{animalBean.animal.value}
3) When you post your form then animal object will be updated automatic. Property action listeners are unnecessary.

generate Primefaces MenuModel from database

i want to ask how to make generate menumodel from database using recursive function.
i already make this class but it's not working. please help me,i already find and trying for a week .thanks
public class MenuDAOImpl extends ManagerBase<MenuMaster> implements MenuDAO {
private List<MenuMaster> list;
private List<MenuData> datas;
#Override
public MenuModel getMenu() {
MenuModel model = new DefaultMenuModel();
String[] orders = new String[]{"id"};
try {
list = getBySQLQuery("PARENT_MENU_ID=0", orders, 1000);
for (MenuMaster menuMaster : list) {
menuChild(menuMaster);
}
} catch (Exception e) {
}
return model;
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
private List<MenuData> menuChild(MenuMaster master) {
List<MenuData> listChild = new ArrayList<MenuData>();
String[] orders = new String[]{"id"};
try {
MenuData data = new MenuData();
data.mm = master;
data.mms = getBySQLQuery("PARENT_MENU_ID=" + master.getParentMenuId(), orders, 1000);
listChild.add(data);
} catch (Exception e) {
}
return listChild;
}
public class MenuData {
private MenuMaster mm;
private List<MenuMaster> mms;
public MenuData() {
}
public MenuMaster getMm() {
return mm;
}
public void setMm(MenuMaster mm) {
this.mm = mm;
}
public List<MenuMaster> getMms() {
return mms;
}
public void setMms(List<MenuMaster> mms) {
this.mms = mms;
}
}
}
this is my database table (sorry i can't upload images)
ID | MENU_NAME | DISPLAY_NAME | URL |PARENT_MENU_ID |
1 | employee | Employee | /employee.xhtml | 0 |
2 | employeemenu| Employee | /employee.xhtml | 1 |
3 | utils | Utility | | 0 |
7 | asdf | asdf | | 6 |
6 | utilsmenu | test | | 3 |
5 | utilsdata | Admin Config | asdf | 3 |
4 | menu | Menu Editor | /utility/menu.xhtml | 3 |
Here's some code I had lying around, I create the menumodel by appending submenus and menuitems to his getChildren() property
private MenuModel model;
public MenuModel getModel() {
if(model != null) return model;
model = new DefaultMenuModel();
addDynamicMenus();
return model;
}
private void addDynamicMenus(){
if(modules == null){
modules = service.getModulesByUserLogin(loginBean.getUsername());
}
Submenu currfather = null;
for(SpFeModuleForUser s : modules){
if(currfather == null || (!currfather.getId().equals("menu_" + s.getModuleID()))){
currfather = new Submenu();
currfather.setLabel(Modules.getSingleton().getString(s.getModuleName()));
currfather.setId("menu_"+s.getModuleID());
model.addSubmenu(currfather);
}
MenuItem mi = new MenuItem();
mi.setValue(Modules.getSingleton().getString(s.getNAME()));
mi.setId("_" + s.getKey());
mi.setTarget("_self");
mi.setTitle(Modules.getSingleton().getString(s.getNAME() + "_Description"));
mi.setAjax(false);
mi.setUrl(url);
// Add parameters
UIParameter param = new UIParameter();
param.setName("moduleid");
param.setValue(s.getKey());
mi.getChildren().add(param);
mi.setProcess("#all");
currfather.getChildren().add(mi);
}
}

Resources