Precisei implementar um converter JSF para minha classe de Clientes. E ao injetar a classe de serviços (@Inject ClienteService clienteService), estou recebendo NullPointerException. Alguém já passou por isso?
@Inject ClienteService clienteService;
@Override
public Object getAsObject(FacesContext fc, UIComponent uic, String string) {
if (string == null || string.length() == 0 || string.startsWith("-")) {
return null;
}
try {
Integer id = Integer.parseInt(string);
return clienteService.findById(id); // NPE aqui
} catch (NumberFormatException | ConverterException e) {
FacesUtils.error("Erro no converter: " + e.getMessage());
throw new ConverterException("Erro de conversão do JSF - Valor " + string + " não conversível", e);
}
}
@leorbarbosa seguinte o converter não tem nenhum contexto, então não ocorre a injeção de dependência e por isto está null. Converter’s não tem responsabilidade de carregar uma entidade/objeto e sim apenas Converter.
A JavaServer Faces converter class converts strings to objects and objects to strings as required. Several standard converters are provided by JavaServer Faces for this purpose… http://docs.oracle.com/javaee/6/tutorial/doc/bnaus.html
Ou seja ela irá converter um objeto em string e uma string em objeto atuando entre a pagina JSF e seu ManagedBean. Uma dica particular, cria um converter geral pras entidades.
1 curtida
Valeu demais. E como seria um converter geral para entidades?
Eu uso este converter em um dos meus projetos:
@FacesConverter(value="entityConverter", forClass= BaseEntity.class)
public class EntityConverter implements Converter {
public Object getAsObject(FacesContext ctx, UIComponent component,
String value) {
if (value != null) {
return this.getAttributesFrom(component).get(value);
}
return null;
}
public String getAsString(FacesContext ctx, UIComponent component,
Object value) {
if (value != null && ! "".equals(value)) {
BaseEntity entity = (BaseEntity) value;
if (entity.getId() != null) {
this.addAttribute(component, entity);
if (entity.getId() != null) {
return String.valueOf(entity.getId());
}
return (String) value;
}
}
return "";
}
private void addAttribute(UIComponent component, BaseEntity o) {
this.getAttributesFrom(component).put(o.getId().toString(), o);
}
private Map<String, Object> getAttributesFrom(UIComponent component) {
return component.getAttributes();
}
}
E está é a classe abstrata que extende nas minhas entidades, assim generalizo p/ todas classes que extender a classe BaseEntity pode usar este converter. Ignora a interface você não irá precisar.
@MappedSuperclass
public abstract class BaseEntity implements Serializable, IEntity {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id", nullable = false, columnDefinition = "BIGINT UNSIGNED")
protected Long id;
@Column(name = "version")
@Version
private Long version;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getVersion() {
return version;
}
@Override
public int hashCode() {
int hash = 0;
hash += (this.getId() != null ? this.getId().hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
if (this == object)
return true;
if (object == null)
return false;
if (getClass() != object.getClass())
return false;
BaseEntity other = (BaseEntity) object;
if (this.getId() != other.getId() && (this.getId() == null || !this.id.equals(other.id))) {
return false;
}
return true;
}
}
Fica a vontade p/ melhorar a implementação.