[RESOLVIDO] Consulta JPA - ignorar acentuação

Olá pessoal, estou precisando fazer uma consulta usando JPA que ignore a acentuação, ou seja, se eu consultar por ‘joao’ a consulta deve retornar tanto ‘joao’ como ‘joão’. Eu já havia solucionado esse problema em outro projeto criando uma function no BD para retirar os acentos, então eu chamava esta função na consulta. Mas por restrições do projeto, não podemos usar functions no BD. a solução que encontrei foi usar nativeQuery:

String sql = "SELECT p.* FROM pessoa p " + "WHERE lower(TRANSLATE(p.nome, 'ÁÀÃÂÄÉÈẼÊËÍÌĨÎÏÓÒÕÔÖÚÙŨÛÜÇáàãâäéèẽêëíìĩîïóòõôöúùũûüç', " + "'AAAAAEEEEEIIIIIOOOOOUUUUUCaaaaaeeeeeiiiiioooooc')) LIKE '%"+nomeSemAcentos.toLowerCase()+"%' "; Query query = this.em.createNativeQuery(sql, Pessoa.class); return query.getResultList();

Dessa maneira funciona, mas gostaria de saber se existe outra maneira de fazer isso sem usar nativeQuery.

Abraços

Jovem,

Você pode implementar um metodo que remova os acentos do parametro e posteriormente enviar o mesmo para a consulta.

Segue o código que remove acento:


import java.text.Normalizer;

public class Teste {

	public static void main(String[] args) {
		String string = "João e José são irmãos e moram em São Paulo na casa dos seus avós";
		System.out.println(removerAcento(string));
	}
	
	public static String removerAcento(String str) {
	    str = Normalizer.normalize(str, Normalizer.Form.NFD);
	    str = str.replaceAll("[^\\p{ASCII}]", "");
	    return str;
	}
}

Abs,

Isso já está sendo feito. O parâmetro “nomeSemAcentos” da consulta já tem os acentos removidos. O problema é ignorar os acentos dos registros no BD.

De todo jeito, obrigado.

Jovem,

Entendi o seu questionamento. Não conheço uma outra forma desconsiderando o native query ou uma função implementada no banco de dados.

Abs,

Jovem,

Procurei no guj e encontrei o mesmo problema citado. Mas a solução proposta não foge do Query Native.

http://www.guj.com.br/java/212706-accent-insensitive-hibernate

Abs,

Pois é. Acho que vai ter que ser feito assim mesmo. Valeu!

Pessoal, me deparei outro problema. Algumas das classes de domínio herdam de uma classe genérica que possui alguns atributos e métodos. Entre os atributos está o id. Então, nessas classe eu não consigo fazer a consulta pois dá a seguinte mensagem de erro:

Exception Description: The primary key read from the row [DatabaseRecord( => 1 curso.codigo => 001 curso.nome => Curso 01 curso.regime_matricula_id => 3 curso.unidade_organizacional_id => 23 curso.modalidade_ensino_id => 1 curso.projeto_pedagogico => null curso.projeto_pedagogico_nome_arquivo => Projeto)] during the execution of the query was detected to be null. Primary keys must not contain null.

Pesquisei sobre o erro e tudo que encontro é que ele é decorrente do fato de o toplink diferencia maiúsculas e minúsculas, ou seja, se no BD está “ID” e na aplicação, “id”, ocorre esse erro. Mas este não é o caso já que tanto no BD como na aplicação id está em caixa baixa. Acredito que seja alguma coisa ligada a essa herança. Alguém ajuda??

Problema resolvido. Pesquisei um pouco mais e descobri que quando o nome da coluna não é definido na anotação @Column, por padrão o JPA seta o nome em caixa alta. No meu caso tive que definir o nome da coluna em caixa baixa.

[quote=rpfragoso]Isso já está sendo feito. O parâmetro “nomeSemAcentos” da consulta já tem os acentos removidos. O problema é ignorar os acentos dos registros no BD.

De todo jeito, obrigado.[/quote]

Cria uma coluna extra na tabela. Nesta coluna guardas, os nomes todos em maiúsculas e sem acentuação. Na pesquisa vais procurar correspondência a esta coluna.
Por exemplo, João, Joao, joao e JoAo, dariam sempre JOAO nesta coluna.

Hoje acabei caindo nesse post, e encontramos uma solução que, pelo menos para min é mais interessante,
a solução seria, graças à JPA 2.1, conseguimos chamar uma função do banco, de dentro de uma JPQL.
mais informações:
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Support_for_Native_Database_Functions#FUNC
O Eclipse link na versão 2.4 implementa esta feature.