I am getting the null Converter error for what I thought was a very simple scenario:
<!-- My View -->
<ui:composition template="/template/template_v1.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<!-- Simplified for clarity -->
<h:form>
<div class="block-panel customer-data">
<h:outputLabel for="txtUsername">Username:</h:outputLabel>
<h:inputText id="txtUsername" name="Username"
value="#{userBean.user.id}"
styleClass="text" />
<rich:message id="errorUsername" for="txtUsername"/>
</div>
<!-- Other fields omitted for clarity -->
</h:form>
/* The User Bean - simplified */
@ManagedBean
@ViewScoped
public class UserBean implements Serializable {
private User user;
public User getUser() {
// Contains logic for reading a user from the database or creating a new
// user object
return user;
}
public void setUser(User user) {
this.user = user;
}
}
/* The user Entity - Simplified */
@Entity
@Table(name = "user")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "user_type", discriminatorType = DiscriminatorType.STRING)
public class User implements IEntity<String>, Serializable {
private static final long serialVersionUID = 1L;
private String id;
@Id
@Column(name = "username", length = 50)
@NotNull(message = "{userIdMandatory}")
@Size(max = 50)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
}
/* The IEntity interface */
public interface IEntity<ID extends Serializable> {
ID getId();
void setId(final ID pId);
}
So essentially I’m trying to bind a string property of my user entity to a inputText field. As far as I’m concerned there should be no need for a conversion so I shouldn’t be getting the error I’m seeing.
Interestingly, if I add the following getter and setter to my entity:
public String getTmpId() {
return this.id;
}
public void setTmpId(String id) {
this.id = id;
}
And then make the necessary changes to my view to bind to tmpId rather than id, everything works as expected.
This seems like a bug to me either to do with the fact that I am binding to a getter/setter defined in an interface, defined in a generic interface or because the getter is marked with the Id attribute. I would appreciate someone else’s ideas however.
As an aside, I have inherited this design and don’t particularly like it so I may just end up refactoring it to introduce a new username property rather than trying to use the Id.
To the best of my knowledge I believe this is caused by an obscure bug in BeanELResolver which is used to get the type of the property being bound to – rather than returning String it is returning Serializable, for which there is no converter and hence the error I am seeing.
It’s not particularly elegant, but I have worked around this by adding a userId property to my userBean and then binding to that in my view instead of the Id property on the user entity. I then use that value to set the Id manually on the entity when I save it: