PrimeFaces SelectOneMenu Converter breaks component - jsf

Given the component: https://www.primefaces.org/showcase/ui/input/oneMenu.xhtml
Full source for my test is at: https://github.com/dannymk/PrimefacesTest
Can't get the component to work with an Object using a converter. Not sure how to solve this one.
package org.primefaces.test;
import java.io.Serializable;
public class Player implements Serializable {
private Integer id;
private String name;
Player(Integer id, String name){
this.id = id;
this.name = name;
}
/**
* #return the id
*/
public Integer getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(Integer id) {
this.id = id;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}
package org.primefaces.test;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
*
* #author Daniel Maldonado
*/
public class PlayerService implements Serializable{
private List<Player> available = new ArrayList<>();
public PlayerService() {
available.add(new Player(1, "One"));
available.add(new Player(2, "Two"));
available.add(new Player(3, "Three"));
available.add(new Player(4, "Four"));
available.add(new Player(5, "Five"));
}
/**
* #return the available
*/
public List<Player> getAvailable() {
return available;
}
/**
* #param available the available to set
*/
public void setAvailable(List<Player> available) {
this.available = available;
}
}
package org.primefaces.test;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* #author Daniel Maldonado
*/
#Named
#FacesConverter(value = "playerConverter", managed = true)
public class PlayerConverter implements Converter<Player> {
#Inject
PlayerService service;
#Override
public Player getAsObject(FacesContext context, UIComponent component, String value) {
if (value != null && value.trim().length() > 0) {
Player found = service.getAvailable().stream()
.filter(player -> player.getName().equals(value))
.findAny()
.orElse(null);
return found;
}
return null;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Player o) {
if (o != null){
return o.getName();
}
return null;
}
}
package org.primefaces.test;
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;
import lombok.Data;
#Data
#Named
#ViewScoped
public class TestView implements Serializable {
private String hello;
private List<Player> available;
private Player selected;
#Inject
PlayerService service;
#PostConstruct
public void init() {
setHello("Welcome to PrimeFaces!!!");
this.available = service.getAvailable();
}
/**
* #return the available
*/
public List<Player> getAvailable() {
return available;
}
/**
* #param available the available to set
*/
public void setAvailable(List<Player> available) {
this.available = available;
}
/**
* #return the selected
*/
public Player getSelected() {
return selected;
}
/**
* #param selected the selected to set
*/
public void setSelected(Player selected) {
this.selected = selected;
}
/**
* #return the hello
*/
public String getHello() {
return hello;
}
/**
* #param hello the hello to set
*/
public void setHello(String hello) {
this.hello = hello;
}
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>PrimeFaces Test - SelectOneMenu</title>
<h:outputScript name="test.js" />
</h:head>
<h:body>
<h1>#{testView.hello}</h1>
<h:form id="frmTest">
<p:panelGrid id="playerPanel" columns="2">
<p:outputLabel value="Selected player: #{testView.selected.name}" />
<p:selectOneMenu id="playerContainer" value="#{testView.selected}" var="p" converter="playerConverter" >
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{testView.available}" var="actual" itemLabel="#{actual.name}" itemValue="#{actual}" />
<p:column>
#{p.name}
</p:column>
<p:ajax event="valueChange" update="playerPanel" />
</p:selectOneMenu>
</p:panelGrid>
</h:form>
</h:body>
</html>
I get errors like:
java.lang.ClassCastException: java.lang.String cannot be cast to org.primefaces.test.Player
at org.primefaces.test.PlayerConverter.getAsString(PlayerConverter.java:38)
It does not seem to matter what I change and believe me I have tried plenty of implementations of the converter and in the view using "#{palyerConverter}" instead of "playerConverter" and still can't get it to work.

Your problem is at this line:
<f:selectItem itemLabel="Select One" itemValue="" />
Currently you are passing an empty string as the itemValue, which is not expected by your converter. Either use itemValue="#{null}" or totally remove the itemValue from the no select option.
See also:
Best way to add a "nothing selected" option to a selectOneMenu in JSF

Finally got it to work with just a few changes thanks to #Jasper de Vries:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>PrimeFaces Test - SelectOneMenu</title>
<h:outputScript name="test.js" />
</h:head>
<h:body>
<h1>#{testView.hello}</h1>
<h:form id="frmTest">
<p:panelGrid id="playerPanel" columns="2">
<p:outputLabel value="Selected player: #{testView.selected.name}" />
<p:selectOneMenu id="playerContainer" value="#{testView.selected}" var="p" converter="playerConverter">
<f:selectItems value="#{testView.available}" var="actual" itemLabel="#{actual.name}" itemValue="#{actual}" />
<p:column>
#{p.name}
</p:column>
<p:ajax event="valueChange" update="playerPanel" />
</p:selectOneMenu>
</p:panelGrid>
</h:form>
</h:body>
</html>
and specially don't forget to implement the EQUALS method in the Object that is "listed":
package org.primefaces.test;
import java.io.Serializable;
import java.util.Objects;
public class Player implements Serializable {
private Integer id;
private String name;
Player(Integer id, String name){
this.id = id;
this.name = name;
}
#Override
public boolean equals(Object obj) {
if(obj == null)
return false;
if(!(obj instanceof Player))
return false;
Player compare = (Player) obj;
return Objects.equals(compare.getId(), this.getId());
}
#Override
public int hashCode() {
int hash = 1;
return hash * 31 + this.getName().hashCode();
}
/**
* #return the id
*/
public Integer getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(Integer id) {
this.id = id;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}

Related

No matching navigation case

I keep getting this message when trying to run the code below. It is supposed to show the test from the document to be uploaded. This is a Java Server Faces program. Why am I getting this message:Unable to find matching navigation case with from-view-id '/upload.xhtml' for action 'vidClass2.upload' with outcome 'vidClass2.upload'
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body >
<h:form id="form" enctype="multipart/form-data" prependId="false">
<p><h:inputFile id="file" value="#{vidClass2.vidData}">
</h:inputFile>
</p>
<br/>
<h:commandButton id="button" value ="upload" action ="vidClass2.upload">
</h:commandButton>
<p id="textOutput">Text: #{vidClass2.vidName}</p>
</h:form>
</h:body>
</html>
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import javax.servlet.http.Part;
/**
*
* #author David Jennings
*/
#ManagedBean(name = "vidClass2")
#RequestScoped
public class VidClass {
private String userName;
private String vidName;
private Part vidData;
/**
* Creates a new instance of VidClass
*/
public VidClass() {
}
/**
* #return the userName
*/
public String getUserName() {
return userName;
}
/**
* #param userName the userName to set
*/
public void setUserName(String userName) {
this.userName = userName;
}
/**
* #return the vidName
*/
public String getVidName() {
return vidName;
}
/**
* #param vidName the vidName to set
*/
public void setVidName(String vidName) {
this.vidName = vidName;
}
/**
* #return the vidData
*/
public Part getVidData() {
return vidData;
}
/**
* #param vidData the vidData to set
*/
public void setVidData(Part vidData) {
this.vidData = vidData;
}
public void upload() {
if (null != vidData) {
try {
InputStream is = vidData.getInputStream();
vidName = new Scanner(is).useDelimiter("\\A").next();
} catch (IOException ex) {
}
}
}
}
enter image description here
in case you are using JavaBeans components on yours page you should use expression #{bean.method} in action.
<h:commandButton id="button" value ="upload" action ="#{vidClass2.upload}"/>

Error : javax.el.PropertyNotFoundException: Target Unreachable, 'null' returned null [duplicate]

This question already has answers here:
Identifying and solving javax.el.PropertyNotFoundException: Target Unreachable
(18 answers)
Closed 7 years ago.
I got this error below when I was running my JSF page.
javax.el.PropertyNotFoundException: Target Unreachable, 'null' returned null..
Warning: /createStaff.xhtml #33,125
value="#{staffBean.staff.firstName}": Target Unreachable, 'null'
returned null javax.el.PropertyNotFoundException: /createStaff.xhtml
#33,125 value="#{staffBean.staff.firstName}": Target Unreachable,
'null' returned null
I don't get why I will run into the error when I use value="#{staffBean.staff.firstName}". There is no problem when I use the value="#{staffBean.userName}" and value="#{staffBean.passWord}" above.
This is my createStaff.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Create Staff</title>
</h:head>
<h:body>
<f:view>
<h:form>
<p:panel id ="panel" header="Staff Creation">
<p:messages id="msgs" />
<h:panelGrid columns="3" columnClasses="label, value">
<h:outputText value="Username: *" />
<p:inputText id="username" value="#{staffBean.userName}" required="true" label="Username">
</p:inputText>
<p:message for="username" />
<h:outputLabel for="pwd1" value="Password 1: *" />
<p:password id="pwd1" value="#{staffBean.passWord}" match="pwd2" label="Password 1" required="true" feedback="true" />
<p:message for="pwd1" />
<h:outputLabel for="pwd2" value="Password 2: *" />
<p:password id="pwd2" value="#{staffBean.passWord}" label="Password 2" required="true" feedback="true" />
<p:message for="pwd2" />
<h:outputText value="First name: *" />
<p:inputText id="firstname" value="#{staffBean.staff.firstName}" required="true" label="Username">
</p:inputText>
<p:message for="firstname" />
<h:outputText value="Last name: *" />
<p:inputText id="lastname" value="#{staffBean.staff.lastName}" required="true" label="Username">
</p:inputText>
<p:message for="lastname" />
<h:outputText value="Last name: *" />
<p:selectOneRadio id="genderconsole" value="#{staffBean.staff.gender}" required="true">
<f:selectItem itemLabel="Male" itemValue="Male" />
<f:selectItem itemLabel="Female" itemValue="Female" />
</p:selectOneRadio>
<p:message for="genderconsole" />
<p:commandButton value="Create Staff"
id="ajax"
update="panel">
</p:commandButton>
</h:panelGrid>
</p:panel>
</h:form>
</f:view>
</h:body>
</html>
This is my StaffBean.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package managedbean;
import entities.Staff;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import sessionBean.staffSessionBeanLocal;
#Named(value = "staffBean")
#SessionScoped
//#ViewScoped
public class StaffBean implements Serializable {
#EJB
private staffSessionBeanLocal staffSession;
private String userName;
private String passWord;
private String loginStatus;
private Staff staff;
...........
////Code removed
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String getLoginStatus() {
return loginStatus;
}
public void setLoginStatus(String loginStatus) {
this.loginStatus = loginStatus;
}
public Staff getStaff() {
return staff;
}
public void setStaff(Staff staff) {
this.staff = staff;
}
}
This is my staff entity.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package entities;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
#Entity
public class Staff extends User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String imageURL;
#ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
private List<Roles> roles = new ArrayList<Roles>();
#Override
public Long getId() {
return id;
}
#Override
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 Staff)) {
return false;
}
Staff other = (Staff) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entities.Staff[ id=" + id + " ]";
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public List<Roles> getRoles() {
return roles;
}
public void setRoles(List<Roles> roles) {
this.roles = roles;
}
}
This is my User class which Staff class extends from.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package entities;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
#MappedSuperclass
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String password;
private Timestamp joinDate;
private String userType;
private String gender;
private String email;
private String contactNo;
private String firstName;
private String lastName;
private Timestamp dOB;
private String address;
private String accountStatus;
private int numOfFailLogin;
private String maritalStatus;
private String activationCode;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 User)) {
return false;
}
User other = (User) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entities.User[ id=" + id + " ]";
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Timestamp getJoinDate() {
return joinDate;
}
public void setJoinDate(Timestamp joinDate) {
this.joinDate = joinDate;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getContactNo() {
return contactNo;
}
public void setContactNo(String contactNo) {
this.contactNo = contactNo;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Timestamp getdOB() {
return dOB;
}
public void setdOB(Timestamp dOB) {
this.dOB = dOB;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getAccountStatus() {
return accountStatus;
}
public void setAccountStatus(String accountStatus) {
this.accountStatus = accountStatus;
}
public String getMaritalStatus() {
return maritalStatus;
}
public void setMaritalStatus(String maritalStatus) {
this.maritalStatus = maritalStatus;
}
public int getNumOfFailLogin() {
return numOfFailLogin;
}
public void setNumOfFailLogin(int numOfFailLogin) {
this.numOfFailLogin = numOfFailLogin;
}
public String getActivationCode() {
return activationCode;
}
public void setActivationCode(String activationCode) {
this.activationCode = activationCode;
}
}
You have no property firstName in your entity staff
UPDATE:
Looks like your staffobject is null add:
#PostConstruct
public void init() {
staff = new Stuff();
}
The error suggests that when the "firstName" is being accessed, it cannot be reached. So the "Staff" has not been constructed yet.
Add a method to your managed bean, this will resolve the issue.
#PostConstruct
public void init() {
staff= new Staff ();
}
For better understanding of why you should do it that way and not
Staff staff = new Staff();
JSF - what is the difference between #PostConstruct and direct method call from constructor?

Page Bean not saved in FlowScope Jsf 2.2

While i create a application my page bean not saved in #FlowScoped . by default stored in Request scope here my code :
enter code here
package com.webage.beans;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.flow.FlowScoped;
#ManagedBean(name="flow1")
#FlowScoped(value = "flow1")
public class Flow1Bean implements Serializable {
public String cusName;
public String city;
public String getName() {
return this.getClass().getSimpleName();
}
public String doReturnValue() {
return "return1";
}
/**
* #return the cusName
*/
public String getCusName() {
return cusName;
}
/**
* #param cusName the cusName to set
*/
public void setCusName(String cusName) {
this.cusName = cusName;
}
/**
* #return the city
*/
public String getCity() {
return city;
}
/**
* #param city the city to set
*/
public void setCity(String city) {
this.city = city;
}
}
My Xhtml file here i'm getting input from page and store it in page bean.:
<p>
<span id="param1FromFlow1">Flow bean
param1Value:<h:inputText id="input"
value="#{flow1.cusName}" /> </span>
</p>
<h:outputText value="#{null != facesContext.application.flowHandler.currentFlow}" >
</h:outputText>
<p></p>
<h:commandButton type="submit" value="Next" styleClass="commandButton"
id="button1" action="flow1a"></h:commandButton>
<p></p>
The below code return "false" in flow/flow1.xhtml file
<h:outputText value="#{null != facesContext.application.flowHandler.currentFlow}" >
</h:outputText>
Flowscope is a CDI scope. Use #Named instead of #ManagedBean.

JSF: Bean constructor called twice on initial loading of page

I am reading Java EE 7 tutorial. In chapter 13.12, there is an example application, ajaxguessnumber. I run the example in Glassfish 4 and everything works fine. I then put System.out.println in bean constructor and I realized that the constructor is being called twice during initial page loading. Why is that so, even for #SessionScoped bean?
Here is the xhtml file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<h:outputStylesheet library="css" name="default.css"/>
<title>Ajax Guess Number Facelets Application</title>
</h:head>
<h:body>
<h:form id="AjaxGuess">
<h:graphicImage value="#{resource['images:wave.med.gif']}"
alt="Duke waving his hand"/>
<h2>
Hi, my name is Duke. I am thinking of a number from
#{dukesNumberBean.minimum} to #{dukesNumberBean.maximum}.
Can you guess it?
</h2>
<p>
<h:inputText
id="userNo"
title="Type a number from 0 to 10:"
value="#{userNumberBean.userNumber}">
<f:validateLongRange
minimum="#{dukesNumberBean.minimum}"
maximum="#{dukesNumberBean.maximum}"/>
</h:inputText>
<h:commandButton id="submit" value="Submit" >
<f:ajax execute="userNo" render="outputGroup" />
</h:commandButton>
</p>
<p>
<h:panelGroup layout="block" id="outputGroup">
<h:outputText id="result" style="color:blue"
value="#{userNumberBean.response}" rendered="#{!facesContext.validationFailed}"/>
<h:message id="errors1"
showSummary="true"
showDetail="false"
style="color: #d20005;
font-family: 'New Century Schoolbook', serif;
font-style: oblique;
text-decoration: overline"
for="userNo"/>
</h:panelGroup>
</p>
</h:form>
</h:body>
</html>
Here is the bean DukesNumberBean
package javaeetutorial.ajaxguessnumber;
import java.io.Serializable;
import java.util.Random;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class DukesNumberBean implements Serializable {
private Integer randomInt = null;
private long maximum = 10;
private long minimum = 0;
public DukesNumberBean() {
System.out.println("Inside DukesNumberBean constructor");
Random randomGR = new Random();
long range = maximum+minimum+1;
randomInt = (int) (minimum + randomGR.nextDouble()*range);
System.out.println("Duke's number: " + randomInt);
}
public long getMaximum() {
return (this.maximum);
}
public void setMaximum(long maximum) {
this.maximum = maximum;
}
public long getMinimum() {
return (this.minimum);
}
public void setMinimum(long minimum) {
this.minimum = minimum;
}
/**
* #return the randomInt
*/
public Integer getRandomInt() {
return randomInt;
}
/**
* #param randomInt the randomInt to set
*/
public void setRandomInt(Integer randomInt) {
this.randomInt = randomInt;
}
}
And here's the bean UserNumberBean
package javaeetutorial.ajaxguessnumber;
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
#Named
#RequestScoped
public class UserNumberBean implements Serializable {
#Inject
DukesNumberBean dukesNumberBean;
private Integer userNumber = null;
String response = null;
public UserNumberBean()
{
System.out.println("Inside constructor");
}
public void setUserNumber(Integer user_number) {
userNumber = user_number;
}
public Integer getUserNumber() {
return userNumber;
}
public String getResponse() {
if ((userNumber != null) && (userNumber.compareTo(dukesNumberBean.getRandomInt()) == 0)) {
return "Yay! You got it!";
}
if (userNumber == null) {
return null;
} else {
return "Sorry, " + userNumber + " is incorrect.";
}
}
}
Any help would be much appreciated. Thank you.
This happens because the scoped objects and injected by CDI using proxies. CDI has first to create a proxy of your object that is a subclass of your real object - this is the first time your constructor gets called because when you instantiate a subclass the parent constructor is always called. And then CDI instantiates your real object in order to inject it - this is the second time your constructor gets called.
A better approach is to put your initialization login in a #PostConstruct method like this.
#PostConstruct
public void init() {
Random randomGR = new Random();
long range = maximum+minimum+1;
randomInt = (int) (minimum + randomGR.nextDouble()*range);
System.out.println("Duke's number: " + randomInt);
}
It will be called only once - when the real object gets instantiated. More info about the proxies you can find here.
EDIT:
I just found another explanation of the problem - here.

#ManagedProperty does not work in a CDI managed bean

I try to learn JSF and encountered on a problem connected with ManagedProperty. However I have tried to use it, it always failed - null exception pointer. What am I doing wrongly?
I have read some "similar posts" on stackoverflow, but they did not helped to me. (I use GlassFish 4.0, JSF 2.2, JDK 1.7, Netbeans 7.3.1 (Java EE pack) and Java EE 6.0)
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
Hello from Facelets
<br/>
User: #{books.user.name}<br/>
1: #{param.pageId}<br/>
2: #{books.pageId}<br/>
<h:form>
<h:inputText value="#{user.name}" /><br/>
<h:inputText value="#{books.v1}" /><br/>
<h:inputText value="#{books.v2}" /><br/>
<h:inputText value="#{books.result}" /><br/>
<h:commandButton value="dodaj" action="#{books.add}" />
</h:form>
</h:body>
</html>
Book
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package tpsa.books.managed;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.faces.bean.ManagedProperty;
/**
*
* #author tomasz
*/
#Named(value = "books")
#RequestScoped
public class Books {
private int v1;
private int v2;
private int result;
#ManagedProperty(value = "#{user}")
private User user;
#ManagedProperty(value="#{param.pageId}")
private int pageId;
/**
* Creates a new instance of Books
*/
public Books() {
}
public void add() {
result = v1 + v2;
}
public int getV1() {
return v1;
}
public void setV1(int v1) {
this.v1 = v1;
}
public int getV2() {
return v2;
}
public void setV2(int v2) {
this.v2 = v2;
}
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
public User getUser() {
if (user == null) {
System.err.println("WTF");
}
return user;
}
public void setUser(User user) {
this.user = user;
}
public int getPageId() {
return pageId;
}
public void setPageId(int pageId) {
this.pageId = pageId;
}
}
User
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package tpsa.books.managed;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
/**
*
* #author tomasz
*/
#Named(value = "user")
#SessionScoped
public class User implements Serializable {
private String name;
/**
* Creates a new instance of User
*/
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
#ManagedProperty is managed bean annotaion, that can't be used with CDI. In above code, you used CDI bean i.e. #Named that is default in JSF 2.2. In this case you can't use ManagedProperty. Please read following line copied from Java EE docs of ManagedBean.
If this annotation is present on a class that does not have the
ManagedBean annotation, the implementation must take no action on this
annotation.
For details see the link:
http://docs.oracle.com/javaee/6/api/javax/faces/bean/ManagedProperty.html
So, use #Inject instead of #ManagedProperty for CDI bean.
#Inject
private User user;
Note that a getter/setter is unnecessary here.

Resources