Referencing CDI producer method result in h:selectOneMenu
Posted
by
user953217
on Stack Overflow
See other posts from Stack Overflow
or by user953217
Published on 2011-09-19T18:04:03Z
Indexed on
2011/11/17
9:50 UTC
Read the original article
Hit count: 289
I have a named session scoped bean CustomerRegistration
which has a named producer method getNewCustomer
which returns a Customer
object. There is also CustomerListProducer
class which produces all customers as list from the database. On the selectCustomer.xhtml page the user is then able to select one of the customers and submit the selection to the application which then simply prints out the last name of the selected customer.
Now this only works when I reference the selected customer on the facelets page via #{customerRegistration.newCustomer}
. When I simply use #{newCustomer}
then the output for the last name is null
whenever I submit the form.
What's going on here? Is this the expected behavior as according to chapter 7.1 Restriction upon bean instantion of JSR-299 spec?
It says:
... However, if the application directly instantiates a bean class, instead of letting the container perform instantiation, the resulting instance is not managed by the container and is not a contextual instance as defined by Section 6.5.2, “Contextual instance of a bean”. Furthermore, the capabilities listed in Section 2.1, “Functionality provided by the container to the bean” will not be available to that particular instance. In a deployed application, it is the container that is responsible for instantiating beans and initializing their dependencies. ...
Here's the code:
Customer.java:
@javax.persistence.Entity
@Veto
public class Customer implements Serializable, Entity {
private static final long serialVersionUID = 122193054725297662L;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Id
@GeneratedValue()
private Long id;
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;
}
@Override
public String toString() {
return firstName + ", " + lastName;
}
@Override
public Long getId() {
return this.id;
}
}
CustomerListProducer.java:
@SessionScoped
public class CustomerListProducer implements Serializable {
@Inject
private EntityManager em;
private List<Customer> customers;
@Inject
@Category("helloworld_as7")
Logger log;
// @Named provides access the return value via the EL variable name
// "members" in the UI (e.g.,
// Facelets or JSP view)
@Produces
@Named
public List<Customer> getCustomers() {
return customers;
}
public void onCustomerListChanged(
@Observes(notifyObserver = Reception.IF_EXISTS) final Customer customer) {
// retrieveAllCustomersOrderedByName();
log.info(customer.toString());
}
@PostConstruct
public void retrieveAllCustomersOrderedByName() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Customer> criteria = cb.createQuery(Customer.class);
Root<Customer> customer = criteria.from(Customer.class);
// Swap criteria statements if you would like to try out type-safe
// criteria queries, a new
// feature in JPA 2.0
// criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
criteria.select(customer).orderBy(cb.asc(customer.get("lastName")));
customers = em.createQuery(criteria).getResultList();
}
}
CustomerRegistration.java:
@Named
@SessionScoped
public class CustomerRegistration implements Serializable {
@Inject
@Category("helloworld_as7")
private Logger log;
private Customer newCustomer;
@Produces
@Named
public Customer getNewCustomer() {
return newCustomer;
}
public void selected() {
log.info("Customer " + newCustomer.getLastName() + " ausgewählt.");
}
@PostConstruct
public void initNewCustomer() {
newCustomer = new Customer();
}
public void setNewCustomer(Customer newCustomer) {
this.newCustomer = newCustomer;
}
}
not working selectCustomer.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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Auswahl</title>
</h:head>
<h:body>
<h:form>
<h:selectOneMenu value="#{newCustomer}" converter="customerConverter">
<f:selectItems value="#{customers}" var="current"
itemLabel="#{current.firstName}, #{current.lastName}" />
</h:selectOneMenu>
<h:panelGroup id="auswahl">
<h:outputText value="#{newCustomer.lastName}" />
</h:panelGroup>
<h:commandButton value="Klick"
action="#{customerRegistration.selected}" />
</h:form>
</h:body>
</html>
working selectCustomer.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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Auswahl</title>
</h:head>
<h:body>
<h:form>
<h:selectOneMenu value="#{customerRegistration.newCustomer}" converter="customerConverter">
<f:selectItems value="#{customers}" var="current"
itemLabel="#{current.firstName}, #{current.lastName}" />
</h:selectOneMenu>
<h:panelGroup id="auswahl">
<h:outputText value="#{newCustomer.lastName}" />
</h:panelGroup>
<h:commandButton value="Klick"
action="#{customerRegistration.selected}" />
</h:form>
</h:body>
</html>
CustomerConverter.java:
@SessionScoped
@FacesConverter("customerConverter")
public class CustomerConverter implements Converter, Serializable {
private static final long serialVersionUID = -6093400626095413322L;
@Inject
EntityManager entityManager;
@Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
Long id = Long.valueOf(value);
return entityManager.find(Customer.class, id);
}
@Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
return ((Customer) value).getId().toString();
}
}
© Stack Overflow or respective owner