Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javax.el.PropretyNotWritableException: The class Article does not have a writable property 'id'

I have an Article DTO (Article.java; code excerpts)

public class Article {

private int id;

public Article() {
    this.id = 0;
}

public Integer getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

I got a view template for editing the article (edit_article.xhtml; code excerpts):

            <h:form id="article_form">
                <p:messages id="messages"/>
                <h:panelGrid columns="2">
                    <h:outputText value="" />
                    <h:inputHidden id="articleId" value="#{hqArticleView.article.id}" converter="javax.faces.Integer" />

                </h:panelGrid>
            </h:form>

and I have a view backing bean (HqArticleView.java; code excerpts):

@Named("hqArticleView")
@RequestScoped
public class HqArticleView implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = 1L;
private Logger log;

@Inject
private IArticleService articleService;

private Article article;
private List<Article> articles;
private Map<String, String> requestParams;

@PostConstruct
private void init() {
    log = LoggerFactory.getLogger(getClass());

    requestParams = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();

    article = new Article();
    article.setPublish(true);

    if (requestParams.containsKey("id")) {
        article.setId(Integer.parseInt(requestParams.get("id")));
        article = articleService.getArticle(article);
    }
}

public Article getArticle() {
    return article;
}

public void setArticle(Article article) {
    this.article = article;
}

public List<Article> getArticles() {
    articles = articleService.getAll();
    Collections.reverse(articles);
    return articles;
}

public void save() {
    log.debug("save pressed");
}

public void edit(Article article) {
    log.debug("edit pressed | id=" + article.getId());
}

public void delete(Article article) {
    log.debug("delete pressed | id=" + article.getId());
}
}

The problem is: I try to access the view I'm getting an error: The class Article does not have a writable property 'id'. all other fields from the Article are processed correctly, only the id is a problem. Strange is, when I wrap the id getter and setter of the Article object inside the bean in:

public void setId(int id){
    this.article.setId(id);
}

public int getId(){
    return this.article.getId();
}

then it works perfectly. what am I missing?

like image 938
rome Avatar asked Nov 16 '13 23:11

rome


1 Answers

When examing the property type for reading, EL looks at the return type of the getter:

public Integer getId() {
    return id;
}

It's thus of type Integer. When EL needs to write the changed value, EL is expecting a setter taking the same type:

public void setId(Integer id) {
    this.id = id;
}

However, no such setter exists in your Article class. Instead, you've a setter taking an int. That's exactly why EL threw a PropertyNotWritableException. It means that it couldn't find a matching setter taking exactly the same type. Fix it accordingly by using Integer instead of int in the setter (or, in this particular case better, by using int instead of Integer in the getter).

That it worked when you exploded the model in the controller (bad practice by the way) is because the getter and setter matched each other.

like image 51
BalusC Avatar answered Nov 03 '22 03:11

BalusC