Consegui resolver o problema sozinho:
Primeiro, criei entidades:
Produto (id, nome, preço, descrição)
Idioma (id, lang)
Product_t (id, prod_id, lang_id, nome, descrição)
então eu criei a função no banco de dados:
FUNCTION 'getLangOrder'(language INTEGER, locale varchar(5)) RETURNS int(11)
BEGIN
case language
when (select id from language where lang=locale) then return 1;
when 2 then return 2;
when 1 then return 3;
else return 4;
end case;
RETURN 5;
END
Esta função ordena minhas traduções pela primeira localidade especificada (se null for padrão) e se isso estiver faltando na ordem definida (inglês (2), esloveno (1), alemão (3))
Em seguida, no meu repositório, em vez de usar a função findAll () padrão do JPA, defini minha própria consulta:
select p.id
, ifnull((select t.description
from product_t t where t.prod_id = p.id
order by getLangOrder(lang_id, @lang) limit 1)
, p.description
) as description
, ifnull((select t.name
from product_t t where t.prod_id = p.proj_id
order by getLangOrder(lang_id, @lang) limit 1)
, p.name
) as name
, p.price
from product p
onde @lang é meu argumento passado (locale lido do cookie)
O que então criou lista com entidades Produto, onde nome e descrição foram traduzidos.