3

In my JSF page, i am trying to remove an element from a collection. Instead of calling the Collection.remove(Object o) method, i think the page calls Vector.remove(int i).

Update: tagsCollection is type of org.eclipse.persistence.indirection.IndirectList

Update: It gives the same exception with Vector

With the code below i get the following error:

java.lang.IllegalArgumentException: Cannot convert com.question.entities.Tags[ tagId=12 ] of type class com.question.entities.Tags to int

<ui:repeat value="#{backingBean.question.tagsCollection}" var="tag" >
    <li>
        <span>#{tag.tagTitle}</span>
        <h:commandButton>
            <f:ajax  event="click" listener="#{backingBean.question.tagsCollection.remove(tag)}"  render="@form" execute="@form"/>
        </h:commandButton>
    </li>
</ui:repeat> 

Update: Here is the minimum code that can generate the exception. It throws the following exception:

java.lang.IllegalArgumentException: Cannot convert true of type class java.lang.Boolean to int

index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form id="form">
            <ui:repeat value="#{backingBean.myList}" var="tag">
                #{tag.booleanValue()}
                <h:commandButton value="Delete">
                    <f:ajax listener="#{backingBean.myList.remove(tag)}"  execute="@form" render="@form"/>
                </h:commandButton>
            </ui:repeat>
        </h:form>
    </h:body>
</html>

BackingBean.java

@Named
@ViewScoped
public class BackingBean implements Serializable {

    private Collection<Boolean> myList = new Vector<Boolean>();

    public BackingBean() {
        myList.add(true);
        myList.add(false);
        myList.add(true);

    }

    public Collection<Boolean> getMyList() {
        return myList;
    }

    public void setMyList(Collection<Boolean> myList) {
        this.myList = myList;
    }

}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Salih Erikci
  • 5,076
  • 12
  • 39
  • 69
  • It is a "Tags" object. – Salih Erikci Nov 20 '14 at 21:16
  • Which remove methods are available to you when you type the dot after `tagsCollection` ? –  Nov 20 '14 at 23:43
  • @SujanSivagurunathan Only remove(Object o) is available. – Salih Erikci Nov 20 '14 at 23:48
  • 1
    Very interesting. I've tried yesterday in my personal laptop with JDK 8 and had the same problem you describe. Now, I've tried it with jdk1.7.0_45 and GF 4.0.0 build 89 and works ok. may be it's a jvm problem? – Mart Dominguez Nov 21 '14 at 14:27
  • @Salih any reason why you are casting the Collection into Vector then back to Collection in the getter ? Anyway, the workaround I have posted works..can you confirm ? –  Nov 21 '14 at 14:44

1 Answers1

0

To be honest, I don't know how JSF handles this in the background, but to avoid it just call your own bean method that does the same

<f:ajax  event="click" listener="#{backingBean.removeTag(backingBean.question, tag)}"  render="@form" execute="@form"/>

public void removeTag(Question question, Tag tag) {
    question.getTagsCollection().remove(tag);
}
Predrag Maric
  • 23,938
  • 5
  • 52
  • 68
  • I already know, i can do that with a backing bean method. I want to do it directly without extra method. – Salih Erikci Nov 20 '14 at 16:52
  • @SalihErikci What type is `tagsCollection`? – Predrag Maric Nov 20 '14 at 16:52
  • I don't know what type it is exactly. It is instantiated by JPA. It is defined as private Collection tagsCollection; – Salih Erikci Nov 20 '14 at 17:11
  • @SalihErikci you should know the type of `tagsCollection`. Make sure to declare it as a `List` (despite the kind of `Collection` implementation it uses behind the scenes) – Luiggi Mendoza Nov 20 '14 at 19:37
  • Why should I know? I know it is a collection. (It is declared so.) It should call the right remove() method. Does it matter whether it is List or Set? – Salih Erikci Nov 20 '14 at 19:40
  • @SalihErikci it's like you don't know what you're developing... And yes, depending on your JSF version, it matters. – Luiggi Mendoza Nov 20 '14 at 21:51
  • I don't understand. Can you please explain why the implementation detail really matters. In my application it doesn't matter for me whether the implementation is Set or List. I just use the add() and remove() methods which are the methods of the Collection interface. Isn't this the purpose of the Interfaces? It is clear that this is a bug of JSF. I don't understand why you think that "I don't know what I am developing" – Salih Erikci Nov 20 '14 at 21:54