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

2

14

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?

Weakminded answered 16/11, 2013 at 23:41 Comment(2)
At quick glance, you have some inconsistency of data types in field/getter/setter for "id": once it's "int", once it's "Integer". Could you try changing all of them to "Integer" and check if it helps?Garnes
thx, that was the problem. very dumb mistakeWeakminded
A
30

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.

Aphrodite answered 17/11, 2013 at 13:22 Comment(1)
argh thats dumb. to be honest i don't know why there was type Integer... but that was the problem. thx a lot!Weakminded
P
0

sometimes is the problem in the name of the variable so need to try another name to solve this issue !

Phalanx answered 26/5, 2021 at 22:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.