Como definir a localidade na validação de bean

Por padrão, a Validação de Bean obtém Locale com base em Locale.getDefault (), que é comum a toda a JVM.

Como alterar a localidade do BeanValidation para a chamada de método EJB atual?

Estou usando o JavaEE7 e quero obter benefícios da integração da validação JPA e Bean, ou seja, validação de acionamento automático em eventos de inserção / atualização / exclusão e, na medida do possível, evitar escrever tudo manualmente.

EDITAR

Afinal, estou retornando mensagens não interpoladas do EJB:

public class DoNothingMessageInterpolator implements MessageInterpolator {
    @Override
    public String interpolate(String message, Context context) {
        return message;
    }
    @Override
    public String interpolate(String message, Context context, Locale locale) {
        return message;
    }
}

e depois interpolando-os na camada da Web:

try{
    //invoke ejb
}catch( EJBException ejbex ){
    if( ejbex.getCause() instanceof ConstraintViolationException ){
        ConstraintViolationException cve = (ConstraintViolationException) ejbex.getCause();
        WebUtils.printConstraintViolationMessages("NewConferenceForm:", context, cve, new Locale(languageCtrl.getLocaleCode()) );
        return null;
    }else throw ejbex;
}catch( Exception e ){
        context.addMessage(null, new FacesMessage( FacesMessage.SEVERITY_ERROR, "Oops.", ""));
        return null;
}


public class WebUtils {

    public static void printConstraintViolationMessages(
        String formPrependId, 
        FacesContext context, 
        ConstraintViolationException cve,
        Locale locale )
    {
        Iterator<ConstraintViolation<?>> iter = cve.getConstraintViolations().iterator();
        while( iter.hasNext() ){
            final ConstraintViolation<?> cv = iter.next();

            javax.validation.MessageInterpolator.Context c = new javax.validation.MessageInterpolator.Context()
            {
                @Override public <T> T unwrap(Class<T> type) {
                    try {
                        return type.newInstance();
                    } catch (InstantiationException ex) {
                        Logger.getLogger(ConferencesCtrl.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IllegalAccessException ex) {
                        Logger.getLogger(ConferencesCtrl.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    return null;
                }
                @Override
                public ConstraintDescriptor<?> getConstraintDescriptor() {
                    return cv.getConstraintDescriptor();
                }
                @Override
                public Object getValidatedValue() {
                    return cv.getInvalidValue();
                }
            };

            ResourceBundleMessageInterpolator rbmi = new ResourceBundleMessageInterpolator();
            String interpolatedMsg = rbmi.interpolate(cv.getMessage(), c, locale );

            //TODO: check if clientId exists
            context.addMessage( formPrependId+cv.getPropertyPath().toString(), new FacesMessage( interpolatedMsg ) );
        }
    }

}

questionAnswers(2)

yourAnswerToTheQuestion