não sei se é isso, mas ao colocar o teu parâmetro como ?1 não quer dizer que você a orderm do parâmetro a ser passado seja do número 1, e sim do primeiro valor passado (ficou um tanto confuso, mas vou melhorar a explicação)
Query query = ses.createQuery("from Product usr where usr.id = ?1 ");
//?1 = ao primeiro parâmetro a ser passado, que por default é 0, então o parâmetro deveria ser passado assim:
query.setInteger(0,id);
//Valor 0 de entrada que é o primeiro atributo a ser lido,
//que será o ?1, e não o 1, pois esse se referiria ao 2° parâmetro
Se tivéssemos 2 parâmetros
Integer valor1 = 10;
String valor2 = "xxjamisxx";
Query query = ses.createQuery("from Product usr where usr.id = ?1 and usr.nome = ?2");
query.setInteger(0,valor1);
query.setString(1,valor2);
agora você terá o valor ?1 preenchido pelo setInteger para 0 e o ?2 estará preenchido com o setString para 1
Criando a sua query desta forma você terá benefícios, porque em qualquer momento da sua query você poderá reutilizar o seu ?#, o valor avi estar armazenado
Integer valor1 = 10;
String valor2 = "xxjamisxx";
Query query = ses.createQuery("from Product usr where (usr.id > ?1 or usr.id < ?1 or usr.id = ?1 or usr.id <> ?1) and usr.nome = ?2");
query.setInteger(0,valor1);
query.setString(1,valor2);
se este não for o caso, fica pelomenos uma explicação 