Ced
Ced

Reputation: 17337

OmniFaces @Param fails to use converter to set a primitive property

@Inject @Param(converter = "#{pageConverter}") // or "pageConverter"
private int page;

@Named
@ApplicationScoped
public class PageConverter implements Converter

When using OmniFaces @Param on page, I get an exception

java.lang.IllegalArgumentException: Can not set int field com.example.Bean.page to null value
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
    at sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:80)
    at java.lang.reflect.Field.set(Field.java:758)
    at org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:94)
    ...

My converter is supposed to take care of that, but getAsObject is never called.

This works:

<f:metadata>
    <f:viewParam name="page" value="#{bean.page}">
        <f:converter binding="#{pageConverter}"/>
    </f:viewParam>
</f:metadata>

Upvotes: 1

Views: 304

Answers (1)

BalusC
BalusC

Reputation: 1108722

This problem is three-fold:

  1. CDI doesn't natively support injecting primitive default values (customized producer needed).
  2. @Param has never supported primitives in first place (because, poor practice).
  3. JSF converters are never called when request parameter is entirely absent.

To solve 1 and 2, I have created issue 266 and I will work on that before 2.4 final.

For now, just use Integer instead of int. It's also considered a better practice to not use primitives as model properties, because you can then use null to distinguish "value is never submitted" from "value is submitted, but is empty".

Moreover, JSF converters are never intented as "default value providers". The <f:viewParam> case would also never have triggered the converter when the request parameter is entirely absent. So that it "works" is actually not true. The effect of 0 being set is just result of EL coercion, which didn't involve the converter. Exactly the same problem is demonstrable when you entirely remove the converter from your case.

Upvotes: 2

Related Questions