Kawu
Kawu

Reputation: 14003

JSF converter scope when using CDI (Seam 3) view-scoped

I'm currently reviewing code and found CDI converters like:

@Named
@RequestScoped
public class BankConverter implements Converter, Serializable
{
    @EJB
    private BankService bankService;

    @Override
    public Object getAsObject( FacesContext ctx, UIComponent comp, String identifier )
    {
        if ( identifier == null || identifier.trim().isEmpty() )
        {
            return null;
        }

        Bank bank = null;

        try
        {       
            bank = this.bankService.findByPrimaryKey( Long.valueOf( identifier ) );
        }
        catch( Exception e )
        {
            // omitted
        }

        return bank;
    }

    @Override
    public String getAsString( FacesContext ctx, UIComponent comp, Object obj )
    {
        if ( obj == null || ( ( Bank ) obj ).getId() == null )
        {
            return null;
        }

        return ( ( Bank ) obj ).getId().toString();
    }

}

The converters are basically always used like this (note the converter="#{bankConverter}"):

<p:autoComplete id="bank"
                value="#{employeeDepotManager.selectedBank}"
                var="bnk"
                converter="#{bankConverter}"
                completeMethod="#{autoCompleter.completeBankSearch}"
                itemLabel="#{bnk.name}"
                itemValue="#{bnk}"
                forceSelection="false"
                minQueryLength="3"
                global="true"
                validator="#{employeeDepotManager.validateBank}"
                scrollHeight="200">
    <p:ajax event="itemSelect" update="bank-code bank-name" />
    <p:column>#{bnk.code}</p:column>
    <p:column>#{bnk.name}</p:column>
</p:autoComplete>                    

I am currently discussing with a colleague about which scope would be the best for the converters...

95% of the manager beans referenced from the JSF pages are @ViewScoped and so I thought it would be best for the converters to be @ViewScoped as well (instead of @RequestScoped, which as far as I understand would recreate a converter instance per AJAX request).

Then my colleague added, that the converter should probably be @Dependent as this would automatically put the converters into the scope the the surrounding beans are in. My feeling said, this wouldn't work. However, I couldn't really disagree as my knowledge pretty much ends here.

So, what would probably be the best scope for converters when almost all beans referenced from JSF are @ViewScoped?

PS: Note that we are using Seam 3 to mix @Named and @ViewScoped

Upvotes: 2

Views: 1926

Answers (1)

skuntsel
skuntsel

Reputation: 11742

As most part of the converters are actually stateless, they could easily be @ApplicationScoped, which is, in my opinion, the most natural scope for them. Nonetheless, some converters actually aren't. For example, DateTimeConverter behind <f:convertDateTime> tag does hold some state. Moreover, the default implementation of @FacesConverter uses Application#createConverter(String converterId) that creates a new converter instance when it is needed, so it can be created more than once per request.

Also, as far as I'm concerned custom converters don't have any intersection with the referenced backing beans in terms of scope, so it doesn't matter whether they are ViewScoped or not. What actually matters when choosing scope of a converter is the scope of the state held in the converter instance, as it was rightly spotted by BalusC.

As far as the converter in your question in fact is stateless, it can safely be @ApplicationScoped.

Upvotes: 3

Related Questions