PickList PrimeFaces not working - jsf

I try to use the pickList component of Primefaces. My converter does not work properly and I don't know why.
This is my ManagedBean:
#ManagedBean(name = "comMB")
#SessionScoped
public class TeamCompetitionBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private DualListModel<Team> teams;
List<Team> source;
List<Team> source1;
List<Team> target;
#ManagedProperty("#{team}")
private TeamServiceI teamService;
List<String> teamNameList ;
// public TeamCompetitionBean() {
public DualListModel<Team> getTeams() {
// Players
teamNameList = new ArrayList<String>();
source = new ArrayList<Team>();
target = new ArrayList<Team>();
source.addAll(getTeamService().getTeam());
teams = new DualListModel<Team>(source, target);
return teams;
}
public void setTeams(DualListModel<Team> teams) {
this.teams = teams;
}
public void onTransfer(TransferEvent event) {
StringBuilder builder = new StringBuilder();
for (Object item : event.getItems()) {
builder.append(((Team) item).getTeamName()).append("<br />");
}
FacesMessage msg = new FacesMessage();
msg.setSeverity(FacesMessage.SEVERITY_INFO);
msg.setSummary("Items Transferred");
msg.setDetail(builder.toString());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public TeamServiceI getTeamService() {
return teamService;
}
public void setTeamService(TeamServiceI teamService) {
this.teamService = teamService;
}
public List<Team> getSource() {
return source;
}
public void setSource(List<Team> source) {
this.source = source;
}
public List<Team> getTarget() {
return target;
}
public void setTarget(List<Team> target) {
this.target = target;
}
public void afficher(){
System.out.println(target);
System.out.println(source);
}
}
and this is my entity class that I would like to load in my pickList:
#Entity
#Table(name = "team", catalog = "competition_manager")
public class Team implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer idTeam;
private Stadium stadium;
private League league;
private String teamName;
// getters and setters
#Override
public String toString() {
return teamName.toString();
}
#Override
public boolean equals(Object obj) {
if (!(obj instanceof Team)) {
return false;
}
Team f = (Team) obj;
return (this.idTeam == f.getIdTeam());
}
Now, this is my custom Converter:
#FacesConverter(forClass = Team.class, value = "teamConverter")
public class TeamConverter implements Converter {
Team team;
public Object getAsObject(FacesContext facesContext, UIComponent component,
String value) {
System.out.println("hello object");
if (value == null || value.length() == 0) {
return null;
}
ApplicationContext ctx = FacesContextUtils
.getWebApplicationContext(FacesContext.getCurrentInstance());
TeamBean controller = (TeamBean) ctx.getBean("teamMB");
List<Team> liststagiaire = controller.getTeamList();
for (int i = 0; i < liststagiaire.size(); i++)
{
team = liststagiaire.get(i);
if (team.getIdTeam() == getKey(value)) {
break;
}
}
return team;
}
java.lang.Integer getKey(String value) {
java.lang.Integer key;
key = Integer.valueOf(value);
return key;
}
String getStringKey(java.lang.Integer value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component,
Object object) {
System.out.println("hello string");
if (object == null) {
System.out.println("hello string null");
return null;
}
if (object instanceof Team) {
System.out.println("hello string intance of");
Team o = (Team) object;
String i = getStringKey(o.getIdTeam());
return i;
} else {
System.out.println("hello throw");
throw new IllegalArgumentException("object " + object
+ " is of type " + object.getClass().getName()
+ "; expected type: " + Team.class.getName());
}
}
}
And finally this is my XHTML page:
<p:pickList id="teamPickList" value="#{comMB.teams}" var="team"
itemValue="#{team}" itemLabel="#{team}" converter="teamConverter">
</p:pickList>

Your problem is comming from this line (in your class TeamConverter) :
if (team.getIdTeam() == getKey(value)) {
You can't compare Integer objects like that, because doing like this you are comparing reference. You should replace this line by
if (team.getIdTeam().intValue() == getKey(value).intValue()) {
You have the same problem in your class Team :
return (this.idTeam == f.getIdTeam());
should be replaced by :
return (this.idTeam.intValue() == f.getIdTeam().intValue());
Not related :
You don't need to use getKey and getStringKey, you could replace them simply like this :
getKey(value) // this
Integer.valueOf(value) // by this
and
getStringKey(o.getIdTeam()) // this
o.getIdTeam().toString() // by this
Also you should replace itemLabel="#{team}" by itemLabel="#{team.teamName}" in your view.

Related

p:orderList converter getAsObject() doesn't call Object.toString()

I've written a custom converter as follows:
#FacesConverter(value = "orderListConverter")
public class OrderListConverter implements Converter {
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
Object ret = null;
if (component instanceof OrderList) {
Object list = ((OrderList) component).getValue();
ArrayList<ExampleEntity> al = (ArrayList<ExampleEntity>) list;
for (Object o : al) {
String name = "" + ((ExampleEntity) o).getName();
if (value.equals(name)) {
ret = o;
break;
}
}
}
return ret;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value)
{
String str = "";
if (value instanceof ExampleEntity) {
str = "" + ((ExampleEntity) value).getNumber();
}
return str;
}
}
My ExampleEntity is implemented as follows:
public class ExampleEntity {
private String name;
private int number;
public ExampleEntity(String name, int number) {
this.name = name;
this.number = number;
}
#Override
public String toString() {
return "toString(): [name=" + name + ", number=" + number + "]";
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
the orderList-Component from Primefaces looks like that:
<p:orderList value="#{orderListBean.exampleList}"
var="exampleEntity" itemValue="#{exampleEntity}"
converter="orderListConverter">
<p:column style="width:25%">
#{exampleEntity.number}
</p:column>
<p:column style="width:75%;">
#{exampleEntity.name}
</p:column>
</p:orderList>
and the bean is implemented as follows:
#SessionScoped
#ManagedBean(name = "orderListBean")
public class OrderListBean {
private List<ExampleEntity> exampleList;
#PostConstruct
public void init() {
exampleList = new ArrayList<ExampleEntity>();
exampleList.add(new ExampleEntity("nameOne", 1));
exampleList.add(new ExampleEntity("nameTwo", 2));
exampleList.add(new ExampleEntity("nameThree", 3));
exampleList.add(new ExampleEntity("nameFour", 4));
exampleList.add(new ExampleEntity("nameFive", 5));
}
public List<ExampleEntity> getExampleList() {
return exampleList;
}
public void setExampleList(List<ExampleEntity> exampleList) {
this.exampleList = exampleList;
}
}
1) when debugging, the value Parameter of getAsObject() contains
the number of the ExampleEntity, but I had expected the
toString() method of ExampleEntity to be called!
2) What is the correct content for itemValue attribute?
Is it a kind of convention over configuration? Or how does the component
'know', to use the whole object, when inserting exampleEntity into itemValue
Hope everything is clear! Tanks a lot for any explanation!
Converters basically serve to transform values in 2 directions:
Server to client, when the value is rendered.
Client to server, when the value is submitted.
In your getAsString you established, that the string representation, the one which client uses, is exampleEntity's number. So that's what gets rendered to client as a value. And later, when the client submits its value, that value is number. To convert it to the object (server) representation, the getAsObject called with the number as a parameter.
The server can't possibly call getAsObject with exampleEntity.toString(), because it doesn't have the exampleEntity instance at that point, only the submitted number.
To illustrate, this should hold:
obj.equals(conv.getAsObject(ctx, comp, conv.getAsString(ctx, comp, obj)));
getAsObject and getAsString should be inversive in their input and output.
To answer your 2nd question: that depends on your needs. You could say itemValue="#{exampleEntity.number}", but that would make sense only if you're not interested in the exampleEntity itself, i.e. on submit you would get the number from the client and that's all you need for your server-side logic.
#FacesConverter(value = "EntityConverter")
public class EntityConverter implements Converter, Serializable {
private static final long serialVersionUID = 1L;
public EntityConverter() {
super();
}
#Override
public Object getAsObject(final FacesContext context, final UIComponent component, final String value) {
if (value == null) {
return null;
}
return fromSelect(component, value);
}
/**
* #param currentcomponent
* #param objectString
* #return the Object
*/
private Object fromSelect(final UIComponent currentcomponent, final String objectString) {
if (currentcomponent.getClass() == UISelectItem.class) {
final UISelectItem item = (UISelectItem) currentcomponent;
final Object value = item.getValue();
if (objectString.equals(serialize(value))) {
return value;
}
}
if (currentcomponent.getClass() == UISelectItems.class) {
final UISelectItems items = (UISelectItems) currentcomponent;
final List<Object> elements = (List<Object>) items.getValue();
for (final Object element : elements) {
if (objectString.equals(serialize(element))) {
return element;
}
}
}
if (!currentcomponent.getChildren().isEmpty()) {
for (final UIComponent component : currentcomponent.getChildren()) {
final Object result = fromSelect(component, objectString);
if (result != null) {
return result;
}
}
}
if (currentcomponent instanceof OrderList) {
Object items = ((OrderList) currentcomponent).getValue();
List<Object> elements = (List<Object>) items;
for (final Object element : elements) {
if (objectString.equals(serialize(element))) {
return element;
}
}
}
return null;
}
/**
* #param object
* #return the String
*/
private String serialize(final Object object) {
if (object == null) {
return null;
}
return object.getClass() + "#" + object.hashCode();
}
#Override
public String getAsString(final FacesContext arg0, final UIComponent arg1, final Object object) {
return serialize(object);
}
}

JSF issue with Scopes

Following is my managed bean code:
public class SelectEntries implements Serializable {
private static final long serialVersionUID = 1217595612573680L;
private List<SelectEntry> selectEntries = new ArrayList<SelectEntry>();
private SelectEntry selectEntry;
#PostConstruct
private void init() {
selectEntries.add(new SelectEntry("1001", new CheckEntry("Line 1"),
new CheckEntry("Line 2"), new CheckEntry("Line 3")));
selectEntries.add(new SelectEntry("1002", new CheckEntry("Line 4"),
new CheckEntry("Line 5"), new CheckEntry("Line 6")));
selectEntries.add(new SelectEntry("1003", new CheckEntry("Line 7"),
new CheckEntry("Line 8"), new CheckEntry("Line 9")));
}
public List<SelectEntry> getSelectEntries() {
return selectEntries;
}
public void setSelectEntries(List<SelectEntry> selectEntries) {
this.selectEntries = selectEntries;
}
public SelectEntry getSelectEntry() {
return selectEntry;
}
public void setSelectEntry(SelectEntry selectEntry) {
this.selectEntry = selectEntry;
}
public String getTemplatesString() {
String templatesString = "";
for (CheckEntry oneCheckEntry : getSelectEntry().getCheckEntries()) {
if (oneCheckEntry.getCheck()) {
templatesString += oneCheckEntry.getName();
}
}
return templatesString;
}
}
Here is the SelectEntry class:
public class SelectEntry implements Serializable {
private static final long serialVersionUID = 7298341984562171094L;
private String name;
private List<CheckEntry> checkEntries = new ArrayList<CheckEntry>();
public SelectEntry(String name, CheckEntry... checkEntries) {
this.name = name;
if (checkEntries != null) {
this.checkEntries.addAll(Arrays.asList(checkEntries));
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<CheckEntry> getCheckEntries() {
return checkEntries;
}
public void setCheckEntries(List<CheckEntry> checkEntries) {
this.checkEntries = checkEntries;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SelectEntry other = (SelectEntry) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
And the CheckEntry class:
public class CheckEntry implements Serializable {
private static final long serialVersionUID = 1730874183104100662L;
private String name;
private Boolean check;
public CheckEntry(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getCheck() {
return check;
}
public void setCheck(Boolean check) {
this.check = check;
}
}
I have a simple function in the managed bean to get create a String on the bases of which check entries have been selected.This only functions with SessionScope and if I use RequestScope, the boolean values of CheckEntries are null and I get runtime error. Why is it so?
As per JEE7 tutorial:
Request (#RequestScoped): Request scope persists during a single HTTP
request in a web application. In an application like hello1, where
the application consists of a single request and response, the bean
uses request scope.
So once your page is loaded, the resquest scoped backing bean is gone for subsequent interactions (even ajax).
You should note that it is encouraged to use the scopes from package javax.enterprise.context
For your application, looks like the minimum scope required is ViewScope. Since javax.enterprise.context doesn't implement view scope, you might consider using Omnifaces.

ClassCastException when two controllers used in a single JSF

I am developing a JSF application with JPA using Netbeans. I crate Entity classes and then generate JSF pages from Entity classes through Netbeans. It creates an AbstractFacade, facade extending the abstract facade for each entity, controller bean for each entity and a JSF page. Then I alter and use these generated codes to create my logic.
There is intermittently a ClassCastException when I use two controller beans within a single JSF page. But when I restart the GLassFish server, the exception disappers for some time and appear again and I can not find out what initiated the change.
For example, consider a situation where there is an Entity called Atm.It has a property MedicineGroup, which is also another entity. When an object from Atm entity is going to be saved through a JSF page, I get all the MedicineGroups calling the MedicineGroupController and assigning it to a selected GenericName property of Atm object. This logic works well until that ClassCastException occur.
(The same above method is used in most JSF pages. Atm entity has a property of Vtm. Ampp has peoperties like Atm atm, MeasurmentUnit strengthUnit, Double strength, Double rol, etc.)
I can also get the same thing done by changing the logic so that there will be only one controller for each JSF page, but it is very easy if multiple controller beans can be referred within the same JSF page.
What is wrong here?
I have listed some important code below.
The relevant part of JSF page.
<h:selectOneListbox id="txtGroup" value="#{vtmController.current.medicineGroup}" size="5" >
<f:selectItems value="#{medicineGroupController.items}" var="gp" itemValue="#{gp}" itemLabel="#{gp.name}"/>
</h:selectOneListbox>
Example of an Entity class
#Entity
#Inheritance
public class Vtm extends PharmaceuticalItem implements Serializable {
#ManyToOne
MedicineGroup medicineGroup;
public MedicineGroup getMedicineGroup() {
return medicineGroup;
}
public void setMedicineGroup(MedicineGroup medicineGroup) {
this.medicineGroup = medicineGroup;
}
}
The controller class example which include an auto-generated converter.
#ManagedBean
#SessionScoped
public final class VtmController {
#EJB
private VtmFacade ejbFacade;
SessionController sessionController = new SessionController();
List<Vtm> lstItems;
private Vtm current;
private DataModel<Vtm> items = null;
private int selectedItemIndex;
boolean selectControlDisable = false;
boolean modifyControlDisable = true;
String selectText = "";
public VtmController() {
}
public List<Vtm> getLstItems() {
return getFacade().findBySQL("Select d From Vtm d");
}
public void setLstItems(List<Vtm> lstItems) {
this.lstItems = lstItems;
}
public int getSelectedItemIndex() {
return selectedItemIndex;
}
public void setSelectedItemIndex(int selectedItemIndex) {
this.selectedItemIndex = selectedItemIndex;
}
public Vtm getCurrent() {
if (current == null) {
current = new Vtm();
}
return current;
}
public void setCurrent(Vtm current) {
this.current = current;
}
private VtmFacade getFacade() {
return ejbFacade;
}
public DataModel<Vtm> getItems() {
items = new ListDataModel(getFacade().findAll("name", true));
return items;
}
public static int intValue(long value) {
int valueInt = (int) value;
if (valueInt != value) {
throw new IllegalArgumentException(
"The long value " + value + " is not within range of the int type");
}
return valueInt;
}
public DataModel searchItems() {
recreateModel();
if (items == null) {
if (selectText.equals("")) {
items = new ListDataModel(getFacade().findAll("name", true));
} else {
items = new ListDataModel(getFacade().findAll("name", "%" + selectText + "%",
true));
if (items.getRowCount() > 0) {
items.setRowIndex(0);
current = (Vtm) items.getRowData();
Long temLong = current.getId();
selectedItemIndex = intValue(temLong);
} else {
current = null;
selectedItemIndex = -1;
}
}
}
return items;
}
public Vtm searchItem(String itemName, boolean createNewIfNotPresent) {
Vtm searchedItem = null;
items = new ListDataModel(getFacade().findAll("name", itemName, true));
if (items.getRowCount() > 0) {
items.setRowIndex(0);
searchedItem = (Vtm) items.getRowData();
} else if (createNewIfNotPresent) {
searchedItem = new Vtm();
searchedItem.setName(itemName);
searchedItem.setCreatedAt(Calendar.getInstance().getTime());
searchedItem.setCreater(sessionController.loggedUser);
getFacade().create(searchedItem);
}
return searchedItem;
}
private void recreateModel() {
items = null;
}
public void prepareSelect() {
this.prepareModifyControlDisable();
}
public void prepareEdit() {
if (current != null) {
selectedItemIndex = intValue(current.getId());
this.prepareSelectControlDisable();
} else {
JsfUtil.addErrorMessage(new MessageProvider().getValue("nothingToEdit"));
}
}
public void prepareAdd() {
selectedItemIndex = -1;
current = new Vtm();
this.prepareSelectControlDisable();
}
public void saveSelected() {
if (selectedItemIndex > 0) {
getFacade().edit(current);
JsfUtil.addSuccessMessage(new MessageProvider().getValue("savedOldSuccessfully"));
} else {
current.setCreatedAt(Calendar.getInstance().getTime());
current.setCreater(sessionController.loggedUser);
getFacade().create(current);
JsfUtil.addSuccessMessage(new MessageProvider().getValue("savedNewSuccessfully"));
}
this.prepareSelect();
recreateModel();
getItems();
selectText = "";
selectedItemIndex = intValue(current.getId());
}
public void addDirectly() {
JsfUtil.addSuccessMessage("1");
try {
current.setCreatedAt(Calendar.getInstance().getTime());
current.setCreater(sessionController.loggedUser);
getFacade().create(current);
JsfUtil.addSuccessMessage(new MessageProvider().getValue("savedNewSuccessfully"));
current = new Vtm();
} catch (Exception e) {
JsfUtil.addErrorMessage(e, "Error");
}
}
public void cancelSelect() {
this.prepareSelect();
}
public void delete() {
if (current != null) {
current.setRetired(true);
current.setRetiredAt(Calendar.getInstance().getTime());
current.setRetirer(sessionController.loggedUser);
getFacade().edit(current);
JsfUtil.addSuccessMessage(new MessageProvider().getValue("deleteSuccessful"));
} else {
JsfUtil.addErrorMessage(new MessageProvider().getValue("nothingToDelete"));
}
recreateModel();
getItems();
selectText = "";
selectedItemIndex = -1;
current = null;
this.prepareSelect();
}
public boolean isModifyControlDisable() {
return modifyControlDisable;
}
public void setModifyControlDisable(boolean modifyControlDisable) {
this.modifyControlDisable = modifyControlDisable;
}
public boolean isSelectControlDisable() {
return selectControlDisable;
}
public void setSelectControlDisable(boolean selectControlDisable) {
this.selectControlDisable = selectControlDisable;
}
public String getSelectText() {
return selectText;
}
public void setSelectText(String selectText) {
this.selectText = selectText;
searchItems();
}
public void prepareSelectControlDisable() {
selectControlDisable = true;
modifyControlDisable = false;
}
public void prepareModifyControlDisable() {
selectControlDisable = false;
modifyControlDisable = true;
}
#FacesConverter(forClass = Vtm.class)
public static class VtmControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
VtmController controller = (VtmController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "vtmController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Long getKey(String value) {
java.lang.Long key;
key = Long.valueOf(value);
return key;
}
String getStringKey(java.lang.Long value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Vtm) {
Vtm o = (Vtm) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type "
+ object.getClass().getName() + "; expected type: " + VtmController.class.getName());
}
}
}
}
An Example for a Facade
#Stateless
public class VtmFacade extends AbstractFacade<Vtm> {
#PersistenceContext(unitName = "HOPU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public VtmFacade() {
super(Vtm.class);
}
}
The generated abstract facade and the changes I made.
public abstract class AbstractFacade<T> {
protected Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
public void edit(T entity) {
getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
public List<T> findAll(boolean withoutRetired) {
return findAll(null, null, withoutRetired);
}
public List<T> findAll() {
javax.persistence.criteria.CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
javax.persistence.criteria.CriteriaQuery<T> cq = cb.createQuery(entityClass);
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
return getEntityManager().createQuery(cq).getResultList();
}
public List<T> findAll(String fieldName) {
return findAll(fieldName, "", false);
}
public List<T> findAll(String fieldName, boolean withoutRetired) {
return findAll(fieldName, "", withoutRetired);
}
public List<T> findAll(String fieldName, String fieldValue) {
return findAll(fieldName, fieldValue, false);
}
public List<T> findBySQL(String temSQL) {
TypedQuery<T> qry = getEntityManager().createQuery(temSQL, entityClass);
return qry.getResultList();
}
public List<T> findBySQL(String temSQL, Map<String, Date> parameters) {
TypedQuery<T> qry = getEntityManager().createQuery(temSQL, entityClass);
Set s=parameters.entrySet();
Iterator it=s.iterator();
while (it.hasNext()){
Map.Entry m=(Map.Entry)it.next();
Date pVal = (Date) m.getValue();
String pPara=(String) m.getKey();
qry.setParameter(pPara, pVal, TemporalType.DATE);
System.out.println("Parameter " + pPara + "\tVal" + pVal);
}
return qry.getResultList();
}
private void test(Class myClass, Object ob) {
}
public List<T> findAll(String fieldName, String fieldValue, boolean withoutRetired) {
javax.persistence.criteria.CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
javax.persistence.criteria.CriteriaQuery<T> cq = cb.createQuery(entityClass);
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
ParameterExpression<String> p = cb.parameter(String.class);
Predicate predicateField = cb.like(rt.<String>get(fieldName), fieldValue);
Predicate predicateRetired = cb.equal(rt.<Boolean>get("retired"), false);
Predicate predicateFieldRetired = cb.and(predicateField, predicateRetired);
if (withoutRetired && !fieldValue.equals("")) {
cq.where(predicateFieldRetired);
} else if (withoutRetired) {
cq.where(predicateRetired);
} else if (!fieldValue.equals("")) {
cq.where(predicateField);
}
if (!fieldName.equals("")) {
cq.orderBy(cb.asc(rt.get(fieldName)));
}
return getEntityManager().createQuery(cq).getResultList();
}
public List<T> findExact(String fieldName, String fieldValue, boolean withoutRetired) {
javax.persistence.criteria.CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
javax.persistence.criteria.CriteriaQuery<T> cq = cb.createQuery(entityClass);
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
ParameterExpression<String> p = cb.parameter(String.class);
Predicate predicateField = cb.equal(cb.upper(rt.<String>get(fieldName)), fieldValue.toLowerCase());
Predicate predicateRetired = cb.equal(rt.<Boolean>get("retired"), false);
Predicate predicateFieldRetired = cb.and(predicateField, predicateRetired);
if (withoutRetired && !fieldValue.equals("")) {
cq.where(predicateFieldRetired);
} else if (withoutRetired) {
cq.where(predicateRetired);
} else if (!fieldValue.equals("")) {
cq.where(predicateField);
}
if (!fieldName.equals("")) {
cq.orderBy(cb.asc(rt.get(fieldName)));
}
return getEntityManager().createQuery(cq).getResultList();
}
public T findByField(String fieldName, String fieldValue, boolean withoutRetired) {
List<T> lstAll = findExact(fieldName, fieldValue, true);
if (lstAll.isEmpty()) {
return null;
} else {
return lstAll.get(0);
}
}
public T findFirstBySQL(String temSQL) {
TypedQuery<T> qry = getEntityManager().createQuery(temSQL, entityClass);
try {
return qry.getResultList().get(0);
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
public <U> List<T> testMethod(U[] a, Collection<U> all) {
List<T> myList = new ArrayList<T>();
return myList;
}
public <U> List<T> findAll(String fieldName, int searchID, boolean withoutRetired) {
javax.persistence.criteria.CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
javax.persistence.criteria.CriteriaQuery<T> cq = cb.createQuery(entityClass);
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
if (withoutRetired) {
cq.where(cb.and(cb.equal(rt.get("retired"), false)),
(cb.equal(rt.get(fieldName).get("id"), searchID)));
} else {
cq.where(cb.equal(rt.get("retired"), false));
}
return getEntityManager().createQuery(cq).getResultList();
}
public int count() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
cq.select(getEntityManager().getCriteriaBuilder().count(rt));
javax.persistence.Query q = getEntityManager().createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
}
public Double findAggregateDbl(String strJQL){
Query q= getEntityManager().createQuery(strJQL);
try{
return (Double) q.getSingleResult();
}catch (Exception e){
System.out.println(e.getMessage());
return 0.0;
}
}
}
This is the code which is referred by the exception.
AtmController controller = (AtmController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "atmController");
In different instances, this same corresponding place, but a different controller. When error occur once, despite the JSF page access afterwords, the same Controller is giving the error, but after server restart, the controller differs depending on the page where error started to occur.
This is the full stack trace. (The name of the controller classes changes depending on the JSF page I use to access.)
INFO: java.lang.ClassCastException: gov.sp.health.bean.VtmController cannot be cast to gov.sp.health.bean.AtmController
java.lang.ClassCastException: gov.sp.health.bean.VtmController cannot be cast to gov.sp.health.bean.AtmController
at gov.sp.health.bean.AtmController$VtmControllerConverter.getAsObject(AtmController.java:252)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:171)
at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectOneValue(MenuRenderer.java:202)
at com.sun.faces.renderkit.html_basic.MenuRenderer.getConvertedValue(MenuRenderer.java:319)
at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1030)
at javax.faces.component.UIInput.validate(UIInput.java:960)
at javax.faces.component.UIInput.executeValidate(UIInput.java:1233)
at javax.faces.component.UIInput.processValidators(UIInput.java:698)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:508)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1590)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIForm.visitTree(UIForm.java:344)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1170)
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:722)
Converter inside AtmController
#FacesConverter(forClass = Atm.class)
public static class AtmControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
AtmController controller = (AtmController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "atmController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Long getKey(String value) {
java.lang.Long key;
key = Long.valueOf(value);
return key;
}
String getStringKey(java.lang.Long value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Atm) {
Atm o = (Atm) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type "
+ object.getClass().getName() + "; expected type: " + AtmController.class.getName());
}
}
}
Converter inside the VtmController
#FacesConverter(forClass = Vtm.class)
public static class VtmControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
VtmController controller = (VtmController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "vtmController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Long getKey(String value) {
java.lang.Long key;
key = Long.valueOf(value);
return key;
}
String getStringKey(java.lang.Long value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Vtm) {
Vtm o = (Vtm) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type "
+ object.getClass().getName() + "; expected type: " + VtmController.class.getName());
}
}
}
Converter inside the MedicineGroupController
#FacesConverter(forClass = MedicineGroup.class)
public static class MedicineGroupControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
MedicineGroupController controller = (MedicineGroupController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "medicineGroupController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Long getKey(String value) {
java.lang.Long key;
key = Long.valueOf(value);
return key;
}
String getStringKey(java.lang.Long value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof MedicineGroup) {
MedicineGroup o = (MedicineGroup) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type "
+ object.getClass().getName() + "; expected type: " + MedicineGroupController.class.getName());
}
}
}
I used converters for each selectOneListbox. The error did not occur afterwords. Below is a similar example I used. (Not exactly the very same as above code)
Initial Converter
#FacesConverter(forClass = Investigation.class)
public static class InvestigationControllerConverter implements Converter {
public InvestigationControllerConverter() {
}
#Override
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
InvestigationController controller = (InvestigationController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "investigationController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Long getKey(String value) {
java.lang.Long key;
key = Long.valueOf(value);
return key;
}
String getStringKey(java.lang.Long value) {
StringBuilder sb = new StringBuilder();
sb.append(value);
return sb.toString();
}
#Override
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Investigation) {
Investigation o = (Investigation) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type "
+ object.getClass().getName() + "; expected type: " + InvestigationController.class.getName());
}
}
}
Later I changed it like this.
#FacesConverter("ixcon")
public static class InvestigationConverter implements Converter {
public InvestigationConverter() {
}
#Override
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
InvestigationController controller = (InvestigationController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "investigationController");
return controller.getEjbFacade().find(getKey(value));
}
java.lang.Long getKey(String value) {
java.lang.Long key;
key = Long.valueOf(value);
return key;
}
String getStringKey(java.lang.Long value) {
StringBuilder sb = new StringBuilder();
sb.append(value);
return sb.toString();
}
#Override
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Investigation) {
Investigation o = (Investigation) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type "
+ object.getClass().getName() + "; expected type: " + InvestigationController.class.getName());
}
}
}
I used that converter in JSF pages like this.
<p:autoComplete converter="ixcon" widgetVar="aIx" id="acIx" forceSelection="true" value="#{investigationItemValueFlagController.investigation}" completeMethod="#{investigationController.completeItem}" var="ix" itemLabel="#{ix.name}" itemValue="#{ix}" size="30" style="width: 400px;">
<p:ajax process="acIx iif" update="iif tbl" event="itemSelect"/>
</p:autoComplete>

JSF Datamodel & JPA parent to leaves navigation. How to?

My web application is a CRUD web application based on JSF 2.0 / JPA using Java EE 5 and JDK 1.6. Running on Glassfish 3.1. The IDE is Netbeans 7.0. (I do not use EJB, nor CDI).
THE PROBLEM
What I can achieve now is perform CRUD on my entities. Which is fine. For each entity I have:
List.xhtml (LIsting all Datamodel items for that entity in datatable)
Create.xhtml (A form to create a new item)
View.xhtml (a form to view an item)
Edit.xhtml (a form to edit an item)
Structure
entities package: entities.
jpa.controllers package: JPA controllers (Javax persistence..).
jsf package: a managed bean for each entity (session Scoped).
But the main problem is parent-leaf navigation. I want my webapp to do the same thing as the Demo application Agile ScrumToys that comes along shipped with Netbeans 7.0. or the demo webapp from SpringFuse, otherwise :
E.G: When you display a list of WRITERS in a you have the last <h:column> where you put three <h:commandLink /> for editing, viewing and deleting the selected row.
What I intend to do is to add another in the same column that allows me to view a collection of child objects related to that selected row.
Hence, I want to show the list of BOOKS written by a given WRITER.
WRITER 1 ---------- * BOOK (one-to-many) relationship.
When the user clicks on the
<h:commandButton action="#{someManagedBean.showBooksForWriter}" value="#{i18n.listBooks}" /> it forwards him to the /book/List.xhtml (list of the selected WRITEr row should appear). And so on, from the book datatable, from a given row, I click on <h:commandLink action="#{someManagedBean.showReferencesForBook}" value="List of Book References"/> to get the list of references for the given book.
A given hint by #Matt was to use a method in the book managed bean:
public showBooksForWriter(Writer writer) {
// TODO: get the selected writer
// Get the list of books for the selected writer
return "/book/List"; // Outcome
}
And in the view :
<h:datatable value="#{writerController.items}" var="w">
.....
<h:column>
<h:commandButton action="#{bookController.showBooksForWriter(w}" value="Show Books For Writer"/>
</h:column>
....
</h:datatable>
But I could not figure how to (DataModel is driving mad). So if anyone could help! It would be very appreciated!
Below is my code
the WRITER entity:
package entities;
import javax.persistence.*; // other imports
#Entity
#Table(name = "WRITER")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Writer.findAll", query = "SELECT w FROM Writer w"),
#NamedQuery(name = "Writer.findByWriterid", query = "SELECT w FROM Writer w WHERE w.writerid = :writerid"),
#NamedQuery(name = "Writer.findByName", query = "SELECT w FROM Writer w WHERE w.name = :name"),
#NamedQuery(name = "Writer.findBySurname", query = "SELECT w FROM Writer w WHERE w.surname = :surname"),
#NamedQuery(name = "Writer.findByMiddlename", query = "SELECT w FROM Writer w WHERE w.middlename = :middlename"),
#NamedQuery(name = "Writer.findByIsRewarded", query = "SELECT w FROM Writer w WHERE w.isRewarded = :isRewarded")})
public class Writer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#NotNull
#Column(name = "writerid")
private Integer writerid;
#Size(max = 45)
#Column(name = "name")
private String name;
#Size(max = 45)
#Column(name = "surname")
private String surname;
#Size(max = 45)
#Column(name = "middlename")
private String middlename;
#Column(name = "isRewarded")
private Boolean isRewarded;
#ManyToMany(mappedBy = "writerList")
private List<Topic> topicList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "writer")
private List<Evaluation> evaluationList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "writer")
private List<Book> bookList;
public Writer() {
}
public Writer(Integer writerid) {
this.writerid = writerid;
}
public Integer getWriterid() {
return writerid;
}
public void setWriterid(Integer writerid) {
this.writerid = writerid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getMiddlename() {
return middlename;
}
public void setMiddlename(String middlename) {
this.middlename = middlename;
}
public Boolean getIsRewarded() {
return isRewarded;
}
public void setIsRewarded(Boolean isRewarded) {
this.isRewarded = isRewarded;
}
#XmlTransient
public List<Topic> getTopicList() {
return topicList;
}
public void setTopicList(List<Topic> topicList) {
this.topicList = topicList;
}
#XmlTransient
public List<Evaluation> getEvaluationList() {
return evaluationList;
}
public void setEvaluationList(List<Evaluation> evaluationList) {
this.evaluationList = evaluationList;
}
#XmlTransient
public List<Book> getBookList() {
return bookList;
}
public void setBookList(List<Book> bookList) {
this.bookList = bookList;
}
#Override
public int hashCode() {
int hash = 0;
hash += (writerid != null ? writerid.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Writer)) {
return false;
}
Writer other = (Writer) object;
if ((this.writerid == null && other.writerid != null) || (this.writerid != null && !this.writerid.equals(other.writerid))) {
return false;
}
return true;
}
#Override
public String toString() {
return getMiddlename();
}
}
The Writer MANAGED BEAN
package jsf;
import entities.Writer;
import jsf.util.JsfUtil;
import jsf.util.PaginationHelper;
import jpa.controllers.WriterJpaController;
import javax.faces.bean.ManagedBean;
// other imports here
#ManagedBean(name = "writerController")
#SessionScoped
public class WriterController implements Serializable {
#Resource
private UserTransaction utx = null;
#PersistenceUnit(unitName = "writerPU")
private EntityManagerFactory emf = null;
private Writer current;
private DataModel items = null;
private WriterJpaController jpaController = null;
private PaginationHelper pagination;
private int selectedItemIndex;
public WriterController() {
}
public Writer getSelected() {
if (current == null) {
current = new Writer();
selectedItemIndex = -1;
}
return current;
}
private WriterJpaController getJpaController() {
if (jpaController == null) {
jpaController = new WriterJpaController(utx, emf);
}
return jpaController;
}
public PaginationHelper getPagination() {
if (pagination == null) {
pagination = new PaginationHelper(10) {
#Override
public int getItemsCount() {
return getJpaController().getWriterCount();
}
#Override
public DataModel createPageDataModel() {
return new ListDataModel(getJpaController().findWriterEntities(getPageSize(), getPageFirstItem()));
}
};
}
return pagination;
}
public String prepareList() {
recreateModel();
return "List";
}
public String prepareView() {
current = (Writer) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
return "View";
}
public String prepareCreate() {
current = new Writer();
selectedItemIndex = -1;
return "Create";
}
public String create() {
try {
getJpaController().create(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("WriterCreated"));
return prepareCreate();
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
return null;
}
}
public String prepareEdit() {
current = (Writer) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
return "Edit";
}
public String update() {
try {
getJpaController().edit(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("WriterUpdated"));
return "View";
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
return null;
}
}
public String destroy() {
current = (Writer) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
performDestroy();
recreateModel();
return "List";
}
public String destroyAndView() {
performDestroy();
recreateModel();
updateCurrentItem();
if (selectedItemIndex >= 0) {
return "View";
} else {
// all items were removed - go back to list
recreateModel();
return "List";
}
}
private void performDestroy() {
try {
getJpaController().destroy(current.getWriterid());
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("WriterDeleted"));
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
}
}
private void updateCurrentItem() {
int count = getJpaController().getWriterCount();
if (selectedItemIndex >= count) {
// selected index cannot be bigger than number of items:
selectedItemIndex = count - 1;
// go to previous page if last page disappeared:
if (pagination.getPageFirstItem() >= count) {
pagination.previousPage();
}
}
if (selectedItemIndex >= 0) {
current = getJpaController().findWriterEntities(1, selectedItemIndex).get(0);
}
}
public DataModel getItems() {
if (items == null) {
items = getPagination().createPageDataModel();
}
return items;
}
private void recreateModel() {
items = null;
}
public String next() {
getPagination().nextPage();
recreateModel();
return "List";
}
public String previous() {
getPagination().previousPage();
recreateModel();
return "List";
}
public SelectItem[] getItemsAvailableSelectMany() {
return JsfUtil.getSelectItems(getJpaController().findWriterEntities(), false);
}
public SelectItem[] getItemsAvailableSelectOne() {
return JsfUtil.getSelectItems(getJpaController().findWriterEntities(), true);
}
#FacesConverter(forClass = Writer.class)
public static class WriterControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
WriterController controller = (WriterController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "writerController");
return controller.getJpaController().findWriter(getKey(value));
}
java.lang.Integer getKey(String value) {
java.lang.Integer key;
key = Integer.valueOf(value);
return key;
}
String getStringKey(java.lang.Integer value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Writer) {
Writer o = (Writer) object;
return getStringKey(o.getWriterid());
} else {
throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + WriterController.class.getName());
}
}
}
}
JSF Utility Class
package jsf.util;
import javax.faces.application.FacesMessage;
// Other imports here
public class JsfUtil {
public static SelectItem[] getSelectItems(List<?> entities, boolean selectOne) {
int size = selectOne ? entities.size() + 1 : entities.size();
SelectItem[] items = new SelectItem[size];
int i = 0;
if (selectOne) {
items[0] = new SelectItem("", "---");
i++;
}
for (Object x : entities) {
items[i++] = new SelectItem(x, x.toString());
}
return items;
}
public static void addErrorMessage(Exception ex, String defaultMsg) {
String msg = ex.getLocalizedMessage();
if (msg != null && msg.length() > 0) {
addErrorMessage(msg);
} else {
addErrorMessage(defaultMsg);
}
}
public static void addErrorMessages(List<String> messages) {
for (String message : messages) {
addErrorMessage(message);
}
}
public static void addErrorMessage(String msg) {
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
FacesContext.getCurrentInstance().addMessage(null, facesMsg);
}
public static void addSuccessMessage(String msg) {
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
FacesContext.getCurrentInstance().addMessage("successInfo", facesMsg);
}
public static String getRequestParameter(String key) {
return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(key);
}
public static Object getObjectFromRequestParameter(String requestParameterName, Converter converter, UIComponent component) {
String theId = JsfUtil.getRequestParameter(requestParameterName);
return converter.getAsObject(FacesContext.getCurrentInstance(), component, theId);
}
}
JSF Pagination helper
package jsf.util;
import javax.faces.model.DataModel;
public abstract class PaginationHelper {
private int pageSize;
private int page;
public PaginationHelper(int pageSize) {
this.pageSize = pageSize;
}
public abstract int getItemsCount();
public abstract DataModel createPageDataModel();
public int getPageFirstItem() {
return page * pageSize;
}
public int getPageLastItem() {
int i = getPageFirstItem() + pageSize - 1;
int count = getItemsCount() - 1;
if (i > count) {
i = count;
}
if (i < 0) {
i = 0;
}
return i;
}
public boolean isHasNextPage() {
return (page + 1) * pageSize + 1 <= getItemsCount();
}
public void nextPage() {
if (isHasNextPage()) {
page++;
}
}
public boolean isHasPreviousPage() {
return page > 0;
}
public void previousPage() {
if (isHasPreviousPage()) {
page--;
}
}
public int getPageSize() {
return pageSize;
}
} // END of CLASS
The JPA Controller
package jpa.controllers;
import entities.Writer;
// other imports here
public class WriterJpaController implements Serializable {
public WriterJpaController(UserTransaction utx, EntityManagerFactory emf) {
this.utx = utx;
this.emf = emf;
}
private UserTransaction utx = null;
private EntityManagerFactory emf = null;
public EntityManager getEntityManager() {
return emf.createEntityManager();
}
public void create(Writer writer) throws RollbackFailureException, Exception {
if (writer.getTopicList() == null) {
writer.setTopicList(new ArrayList<Topic>());
}
if (writer.getEvaluationList() == null) {
writer.setEvaluationList(new ArrayList<Evaluation>());
}
if (writer.getBookList() == null) {
writer.setBookList(new ArrayList<Book>());
}
EntityManager em = null;
try {
utx.begin();
em = getEntityManager();
List<Topic> attachedTopicList = new ArrayList<Topic>();
for (Topic topicListTopicToAttach : writer.getTopicList()) {
topicListTopicToAttach = em.getReference(topicListTopicToAttach.getClass(), topicListTopicToAttach.getTopicname());
attachedTopicList.add(topicListTopicToAttach);
}
writer.setTopicList(attachedTopicList);
List<Evaluation> attachedEvaluationList = new ArrayList<Evaluation>();
for (Evaluation evaluationListEvaluationToAttach : writer.getEvaluationList()) {
evaluationListEvaluationToAttach = em.getReference(evaluationListEvaluationToAttach.getClass(), evaluationListEvaluationToAttach.getEvaluationPK());
attachedEvaluationList.add(evaluationListEvaluationToAttach);
}
writer.setEvaluationList(attachedEvaluationList);
List<Book> attachedBookList = new ArrayList<Book>();
for (Book bookListBookToAttach : writer.getBookList()) {
bookListBookToAttach = em.getReference(bookListBookToAttach.getClass(), bookListBookToAttach.getBookPK());
attachedBookList.add(bookListBookToAttach);
}
writer.setBookList(attachedBookList);
em.persist(writer);
for (Topic topicListTopic : writer.getTopicList()) {
topicListTopic.getWriterList().add(writer);
topicListTopic = em.merge(topicListTopic);
}
for (Evaluation evaluationListEvaluation : writer.getEvaluationList()) {
Writer oldWriterOfEvaluationListEvaluation = evaluationListEvaluation.getWriter();
evaluationListEvaluation.setWriter(writer);
evaluationListEvaluation = em.merge(evaluationListEvaluation);
if (oldWriterOfEvaluationListEvaluation != null) {
oldWriterOfEvaluationListEvaluation.getEvaluationList().remove(evaluationListEvaluation);
oldWriterOfEvaluationListEvaluation = em.merge(oldWriterOfEvaluationListEvaluation);
}
}
for (Book bookListBook : writer.getBookList()) {
Writer oldWriterOfBookListBook = bookListBook.getWriter();
bookListBook.setWriter(writer);
bookListBook = em.merge(bookListBook);
if (oldWriterOfBookListBook != null) {
oldWriterOfBookListBook.getBookList().remove(bookListBook);
oldWriterOfBookListBook = em.merge(oldWriterOfBookListBook);
}
}
utx.commit();
} catch (Exception ex) {
try {
utx.rollback();
} catch (Exception re) {
throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
}
throw ex;
} finally {
if (em != null) {
em.close();
}
}
}
public void edit(Writer writer) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
// remainder of code goes here
}
public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
// remainder of code goes here
}
public List<Writer> findWriterEntities() {
return findWriterEntities(true, -1, -1);
}
public List<Writer> findWriterEntities(int maxResults, int firstResult) {
return findWriterEntities(false, maxResults, firstResult);
}
private List<Writer> findWriterEntities(boolean all, int maxResults, int firstResult) {
EntityManager em = getEntityManager();
try {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(Writer.class));
Query q = em.createQuery(cq);
if (!all) {
q.setMaxResults(maxResults);
q.setFirstResult(firstResult);
}
return q.getResultList();
} finally {
em.close();
}
}
public Writer findWriter(Integer id) {
EntityManager em = getEntityManager();
try {
return em.find(Writer.class, id);
} finally {
em.close();
}
}
public int getWriterCount() {
EntityManager em = getEntityManager();
try {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
Root<Writer> rt = cq.from(Writer.class);
cq.select(em.getCriteriaBuilder().count(rt));
Query q = em.createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
} finally {
em.close();
}
}
}

selectOneMenu in dataTable, default value not getting set properly

When I place a selectOneMenu within a dataTable, it does not display the correct default value in the selectOneMenu. The datatable is bound to a list of POJO's. The POJO entity Badge references a POJO entity we will call Facility. This Facility should be the selected value of the selectOneMenu in the row (the row being each Badge).
The following is my simple example of a table:
<h:dataTable id="examp" value="#{managedBean.badges}" var="badge">
<h:column rowHeader="rowie">
<h:selectOneMenu value="#{badge.facility}" id="col1">
<f:converter converterId="facilityConverter" />
<f:selectItems value="#{managedBean.facilities}"
/>
</h:selectOneMenu>
</h:column>
</h:dataTable>
The selectItems are a List of SelectItem objects that are created at PostConstruct. These are within my managedbean that is in ViewScope.
public class ListBadges extends BaseBean {
private List<Badge> badges = new ArrayList<Badge>();
private List<SelectItem> facilities = new ArrayList<SelectItem>();
public ListBadges() {
getBadgesFromDatabase(true);
}
#PostConstruct
public void init() {
if (facilities.size() <= 0) {
try {
List<Facility> facilityBeans = FacilityHelper.getFacilities();
for (Facility fac : facilityBeans) {
facilities.add(new SelectItem(fac, fac.getFacilityName()));
}
} catch (tException e) {
log.error("ListBadges.init(): " + e.getMessage());
e.printStackTrace();
}
}
}
public void getBadgesFromDatabase(boolean forceRefresh) {
if (forceRefresh || badges == null || badges.isEmpty())
badges = BadgeHelper.getBadgeList();
}
///
/// Bean Properties
///
public List<Badge> getBadges() {
return badges;
}
public void setBadges(List<Badge> badges) {
this.badges = badges;
}
public List<SelectItem> getFacilities() {
return facilities;
}
public void setFacilities(List<SelectItem> facilities) {
this.facilities = facilities;
}
Stepping through the code I confirm that all of the data is correct. In my converter, I verified that the arguments passed to getAsString is correct, so it should have identified the correct item.
#FacesConverter("facilityConverter")
public class FacilityConverter implements Converter {
#Override
public Object getAsObject(FacesContext context, UIComponent component, String from) {
try {
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
ListBadges neededBean =
(ListBadges) context.getApplication().getELResolver().getValue(elContext, null, "managedBean");
long id = Long.parseLong(from);
for (SelectItem sItem : neededBean.getFacilities()) {
Facility facility = (Facility)sItem.getValue();
if (facility.getFacilityId() == id)
return facility;
}
} catch (Exception e) {
}
return null;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
try {
Facility facility = (Facility)value;
return facility.getFacilityId() + "";
} catch (Exception e) {
}
return null;
}
}
Here is the Facility class which has equals and hashCode implemented:
public class Facility implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private long facilityId;
private String facilityName;
private String address1;
private String address2;
private String city;
private String state;
private String postalCode;
private String url;
private String phone;
private String siteManager;
public Facility() {
}
public Facility(String facilityName) {
this.facilityName = facilityName;
}
public Facility(String facilityName,
String address1, String address2, String city, String state,
String postalCode, String url, String phone, String siteManager) {
this.facilityName = facilityName;
this.address1 = address1;
this.address2 = address2;
this.city = city;
this.state = state;
this.postalCode = postalCode;
this.url = url;
this.phone = phone;
this.siteManager = siteManager;
}
public long getFacilityId() {
return this.facilityId;
}
public void setFacilityId(long facilityId) {
this.facilityId = facilityId;
}
public String getFacilityName() {
return this.facilityName;
}
public void setFacilityName(String facilityName) {
this.facilityName = facilityName;
}
public String getAddress1() {
return this.address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return this.address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
public String getPostalCode() {
return this.postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getSiteManager() {
return siteManager;
}
public void setSiteManager(String siteManager) {
this.siteManager = siteManager;
}
#Override
public boolean equals(Object o) {
if (!(o instanceof Facility) || (o == null))
return false;
if (o == this)
return true;
Facility obj = (Facility)o;
return obj.getFacilityId() == this.getFacilityId();
}
#Override
public int hashCode() {
return (new Long(this.getFacilityId()).hashCode()) ^
((this.getAddress1() == null) ? 0 : this.getAddress1().hashCode()) ^
((this.getAddress2() == null) ? 0 : this.getAddress2().hashCode()) ^
((this.getCity() == null) ? 0 : this.getCity().hashCode()) ^
((this.getFacilityName() == null) ? 0 : this.getFacilityName().hashCode()) ^
((this.getPhone() == null) ? 0 : this.getPhone().hashCode()) ^
((this.getPostalCode() == null) ? 0 : this.getPostalCode().hashCode()) ^
((this.getSiteManager() == null) ? 0 : this.getSiteManager().hashCode()) ^
((this.getUrl() == null) ? 0 : this.getUrl().hashCode());
}
}
I would greatly appreciate any feedback.
I found the problem and it is nothing to do with JSF.
Eclipse was loading an older version of the Facility bean class that had a programmatic mistake in its equals method. Even after fully cleaning, republishing, cleaning the working directory, restarting the web server, and restarting Eclipse this old class was still getting loaded. I restarted my computer and finally the correct class was being loaded and this problem went away.
Thanks for looking at this BalusC. Without this blog article you wrote I would be completely lost! http://balusc.blogspot.com/2007/09/objects-in-hselectonemenu.html

Resources