I have a (request-scoped) list from which the user may select a \"PQ\" (list of links). When clicked or otherwise entered into the browser the main page for each PQ shall be
There is a better way to get id from url. Just use it in @PostConstruct init() method to get "id" from url:
FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id");
You can still use ViewScoped and @PostConstruct.
The @PostConstruct is invoked directly after bean's construction and all dependency injection (such as @PersistenceContext, @EJB, @ManagedProperty, @Inject, etc..etc..).
The <f:viewParam> sets its value during the update model values phase, which is far after (post)construction of the bean. So inside the @PostConstruct the <f:viewParam> value is simply not yet been set. It'll be still null at that point.
You're close with <f:event type="preRenderView">, but you have to remove the @PostConstruct annotation.
So:
<f:viewParam name="pq" value="#{pqHome.id}">
<f:convertNumber integerOnly="#{true}" />
</f:viewParam>
<f:event type="preRenderView" listener="#{pqHome.init}" />
with
private Integer id;
public void init() {
instance = em.find(PQ.class, id);
}
Unrelated to the concrete problem, I'd suggest to use a Converter for this instead. See also Communication in JSF 2.0 - Converting and validating GET request parameters.
Also the combination @Named @ViewScoped won't work as intended. The JSF-specific @ViewScoped works in combination with JSF-specific @ManagedBean only. Your CDI-specific @Named will behave like @RequestScoped this way. Either use @ManagedBean instead of @Named or use CDI-specific @ConversationScoped instead of @ViewScoped.