0

I have a primefaces selectOneMenu and it uses a javax.faces.convert.Converter for displaying devices.

It works fine only when the key (device's id) is not greater than 127. When it's greater, after clicking a commandButton the selectOneMenu's arrow becomes red and the commandButton's action is not executed.

Why? Any ideas?

<p:selectOneMenu id="deviceActionParameter"
    value="#{sm.ruleConfigureBean.deviceActionParameter}"
    style="width:200px;">
    <f:selectItems value="#{sm.ruleConfigureBean.sensors}"
        var="device" itemLabel="#{device.name}" />
    <f:converter converterId="deviceConverter" />
</p:selectOneMenu>

converter:

@FacesConverter(value = "deviceConverter")
public class DeviceConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String key) {
        DeviceDao deviceDao = GuiceSingleton.getInstance().getInstance(
                DeviceDao.class);
        try {
            Device device = deviceDao.getDeviceById(new Long(key)); // this works
            return device;
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component,
            Object value) {
        if (value != null && value instanceof Device) {
            Device device = (Device) value;
            return "" + device.getIdDevice();
        }
        return "";
    }
}
Teodor
  • 1

2 Answers2

0

I believe it's an optimization of Java Integer caching mechanism,

        Integer int1=128;
        Integer int2=128;

        if(int1==int2)
            System.out.println("yes");
        else
            System.out.println("no");

will show yes for Integers in the range [-128, 127] and no otherwise.
If equals is used than it will be yes all the time.

Solutions:

  • change getDeviceById() to use equals

  • I believe in later versions it is posible to increase this range

  • otherwise stick with Long
Ion Cojocaru
  • 2,583
  • 15
  • 16
  • in getDeviceById() ids are compared by mybatis ("=" in SQL query) and it works fine: the proper object is fetched from the database. and I stick with Long already. – Teodor Apr 02 '13 at 08:48
0

The problem was not in the converter, but in the Device class - I was comparing Longs with ==.

Now it's ok:

@Override
public boolean equals(Object o) {
    if (o instanceof Device) {
        return idDevice.equals(((Device) o).getIdDevice());
    }
    return false;
}

Thanks for answers :)

Teodor
  • 1