#Ejb doesn't inject in converter - jsf

I'm trying to Write my own converter
I want to Inject my EJBs into my converter with #EJB .
my #EJB works in Other my ManagedBean but it doesn't work here in my converter
#ManagedBean
#ViewScoped
public class ServerTypeConverter implements Converter {
#EJB
private ServerTypeFacade serverTypeFacade;
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value == null || value.isEmpty()) {
return null;
} else {
int id = Integer.parseInt(value);
return serverTypeFacade.findById(id);
}
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null || value.equals("")) {
return "";
} else {
Integer id = ((ServerType) value).getServer_type_id();
return String.valueOf(id);
}
}
}
ServerTypeFacade returns null. why ?
here is the way i use converter
<h:selectOneMenu value="#{serverMB.selectedServerType}">
<f:converter converterId="serverTypeConverter"/>
<f:selectItems value="#{serverMB.serverTypesList}" var="servertypes" itemLabel="#{servertypes.server_type_name}" />
<f:ajax listener="#{serverMB.changeServerType}" render="dd" />
</h:selectOneMenu>

The #EJB in converter works only if you declare it as a managed bean by #ManagedBean and use it as managed bean by #{serverTypeConverter}.
However, you're using the converter as a faces converter by converterId="serverTypeConverter". Apparently you've also declared it as a faces converter by #FacesConverter on the class or <converter> in faces-config.xml.
Those two ways of declaring and using the converter are mutually exclusive. In order to get #EJB to work, you should be using the converter as a managed bean:
<f:converter binding="#{serverTypeConverter}" />
See also:
CDI Injection into a FacesConverter

Related

Injection in a converter does not work in JSF 2.3

Server: Payara 5.183.
When the converter is used, a NullPointerException is raised because the injected EJB is null (System.out.println prints "null").
It works (injection not null) if I use a workaround used before JSF 2.3: replacement of #FacesConverter by #Name.
Converter:
#FacesConverter(value = "compteConverter", managed = true)
public class CompteConverter implements Converter<CompteBancaire> {
#EJB
private GestionnaireCompte gestionnaireCompte;
#Override
public CompteBancaire getAsObject(FacesContext context, UIComponent component, String id) {
if (id == null || id.isEmpty()) {
return null;
}
try {
System.out.println("*****EJB gestionnaireCompte=" + gestionnaireCompte);
return gestionnaireCompte.getCompte(Long.parseLong(id));
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage("Id de compte invalide"), e);
}
}
#Override
public String getAsString(FacesContext arg0, UIComponent arg1, CompteBancaire compte) { ... }
Usage of this converter:
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="id" value="#{operations.compte}"
converter="compteConverter"/>
Is it a bug of Mojarra/Payara (managed = true is not working) or can you help me to find my error?
Managed converters don't work by default. To make them work I added a CDI bean annotated by #FacesConfig (for JSF 2.3 to be used) and #ApplicationScoped (it will be a CDI bean with this annotation).

How to get inputTextArea value into another bean?

I want to get the value with the getter method, but it doesn't work. I use SessionScoped into my two managed-beans.
<h:outputLabel for="commentInput" value="Comment:" />
<p:inputTextarea id="commentInput" value="#{dashboardBean.currentComment}" rows="6" cols="25" label="commentInput" required="true"/>
#ManagedBean
#SessionScoped
public class DashboardBean implements Serializable
{
private String _currentComment = null;
public String getCurrentComment() {
return this._currentComment;
}
public void setCurrentComment(String _currentComment) {
this._currentComment = _currentComment;
}
}
If i call getter in this class, it's works.
But in the other class:
#ManagedBean
#SessionScoped
public class PanelListener extends AjaxBehaviorListenerImpl
{
private DashboardBean _dashDashboardBean = null;
public void editMemo(ActionEvent actionEvent)
{
System.out.println("Statements ==== [ " + _dashDashboardBean.getCurrentComment() + " ]");
}
}
I have an NullPointerException.
You need to use #ManagedProperty annotation to inject one bean into another.
#ManagedProperty("#{dashboardBean}")
private DashboardBean bean;
public DashboardBean getBean(){
return this.bean;
}
public void setBean(DashboardBean bean){
this.bean = bean;
}
Make sure the scope of the ManagedProperty is greater than or equal to the scope of bean in which you are injecting.
so here, DashBoardBean should have scope greater than or equal to PanelListener
Please note that JSF needs public getters and setters to access the fields
You have to use #ManagedProperty annotation. So try this in PanelListener, note that you need a setter to perform the bean injection. You can also only inject beana with greater or same scope to the bean with lower scopes (so for example you can inject SessionScoped to the RequestScoped but not the other way around).
#ManagedProperty("#{dashboardBean}")
private DashboardBean bean;
private void setDashboardBean(DashboardBean bean) {
this.bean = bean;
}

Pick Custom Object from Select one menu JSF Converter Exception [duplicate]

This question already has answers here:
Pick Custom Object from Select one menu JSF [duplicate]
(2 answers)
Closed 9 years ago.
i want to pick custom object from select one menu. it neither shows an error nor values. what to do? please help me. thanks in advance.
Now i'm seeing Null pointer exception at getAsObject at this line:
return getCurrencyService().getCurrencyBtId(currencyId);
this is my xhtml document
<h:panelGrid columns="2">
<p:outputLabel value="" />
<p:selectOneMenu id="CurrencyMenu" value="#{CurrencyMB.currency}" converter="currencyConverter" >
<f:selectItems value="#{CurrencyMB.currencyList}" var="currency" itemValue="#{currency}" itemLabel="#{currency.currencyName}" >
</f:selectItems>
<p:ajax update="currencyOut" />
</p:selectOneMenu>
<p:outputLabel value="Currency Id : #{CurrencyMB.currency.currencyId}" id="currencyOut" />
</h:panelGrid>
this is my managedBean class.
#ManagedBean(name = "CurrencyMB")
#RequestScoped
public class CurrencyManagedBean implements Serializable{
private Currency currency;
private List<Currency> currencyList;
public Currency getCurrency() {
return currency;
}
public void setCurrency(Currency currency) {
this.currency = currency;
}
public List<Currency> getCurrencyList() {
currencyList = new ArrayList<Currency>();
currencyList.addAll(getiCurrencyService().getCurrencies());
return currencyList;
}
public void setCurrencyList(List<Currency> currencyList) {
this.currencyList = currencyList;
}
}
this is my currencyConverter class code:
**#FacesConverter("currencyConverter")
public class CurrencyConverter implements Converter {
#ManagedProperty(value = "#{currencyService}")
private ICurrencyService currencyService;
public ICurrencyService getCurrencyService() {
return currencyService;
}
public void setCurrencyService(ICurrencyService currencyService) {
this.currencyService = currencyService;
}
#Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String value) {
int currencyId = Integer.valueOf(value);
return getCurrencyService().getCurrencyBtId(currencyId);
}
#Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object value) {
Currency currency = (Currency) value;
int currencyId = currency.getCurrencyId();
return String.valueOf(currencyId);
}
}**
As it can be seen in many questions, and their answers, here, #FacesConverter is not eligible for injection. In your case, you try to inject your service via #ManagedProperty, which yields NPE, as Luiggi told you in a comment to your initial question.
With the current JSF release, all you can do to inject services in your converters is to give up using #FacesConverter and switch to using standard #ManagedBean annotation, thus referring to your converter not by id, but by bean name, like in converter="#{currencyConverter}".

JSF 2 <f:selectItems> not recognizing itemLabel and itemValue attributes

I have the following dropdown in a Facelets page:
<h:selectOneMenu value="#{contactBean.selectedContact}" converter="#{contactConverter}">
<f:selectItems value="#{contactsHolder.contacts}" var="contact"
itemLabel="#{contact.firstName}" itemValue="#{contact}" />
</h:selectOneMenu>
The problem is, no matter what I put in for itemLabel (JSF EL expression or just plain text), it doesn't display. Any idea what I'm doing wrong?
Here's ContactConverter:
#ManagedBean(name = "contactConverter")
#RequestScoped
public class ContactConverter implements Converter, Serializable {
#ManagedProperty(value = "#{contactsHolder}")
private ContactsHolder contactsHolder;
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return contactsHolder.getContacts().get(value);
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return ((Contact) value).getContactID();
}
//getter & setters...
}
And ContactsHolder:
#ManagedBean
#SessionScoped
public class ContactsHolder implements Serializable {
private Map<String, Contact> contacts;
#PostConstruct
public void init() {
contacts = new LinkedHashMap<String, Contact>();
//get Contacts data and populate map...
}
//getters & setters...
}
You're feeding a Map<String, Contact> to <f:selectItems value>. Each item in var attribute will be a Map.Entry<String, Contact> which has only getKey() and getValue() methods returning the String map key and Contact map value respectively. The Map.Entry class indeed doesn't have a getFirstName() method.
Fix it accordingly:
<f:selectItems value="#{contactsHolder.contacts}" var="contact"
itemLabel="#{contact.value.firstName}" itemValue="#{contact.value}" />
Or, if you target a Servlet 3.0 / EL 2.2 capable container which allows invoking non-getter methods, so that you can use Map#values() to get a Collection<Contact>:
<f:selectItems value="#{contactsHolder.contacts.values()}" var="contact"
itemLabel="#{contact.firstName}" itemValue="#{contact}" />
Or, make the #{contactsHolder.contacts} a List<Contact> instead so that your initial view code will work:
<f:selectItems value="#{contactsHolder.contacts}" var="contact"
itemLabel="#{contact.firstName}" itemValue="#{contact}" />

ManagedProperty not injected in #FacesConverter

I'm trying to inject a ManagedBean in my FacesConverted the following way:
#ManagedBean
#RequestScoped
#FacesConverter(forClass = Group.class)
public class GroupConverter implements Converter {
#ManagedProperty("#{groupService}")
private GroupService groupService;
#Override
public Group getAsObject(FacesContext context, UIComponent arg1,
String groupName) {
return groupService.findGroupByName(groupName);
}
#Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object group) {
return ((Group) group).getName();
}
public GroupService getGroupService() {
return groupService;
}
public void setGroupService(GroupService groupService) {
this.groupService = groupService;
}
}
The problem is that groupService isn't being injected and I get a NullPointerEx. Shouldn't it be autowired automatically since it's also a ManagedBean? It all works when I change "getAsObject" to "return new Group();" obviously.
Any ideas?
It is likely that you are not resolving the managed bean name.
#ManagedBean(name = "myConverter")
#RequestScoped
#FacesConverter(value = "myConverter")
public class MyConverter implements Converter {
For example, consider these two components:
<h:inputText converter="myConverter" value="#{foo.prop}" />
<h:inputText converter="#{myConverter}" value="#{bar.prop}" />
When the converter is set on the first component, it will be created by Application.createConverter. A converter is not a managed bean. The same rules apply if you match a converter by type.
In the second component, a value expression is used to return a class that implements Converter. This uses the usual managed bean mechanisms. In this case, the #FacesConverter annotation is irrelevant.

Resources