Durante um Hibernate Session
, estou carregando alguns objetos e alguns deles são carregados como proxies devido ao carregamento lento. Está tudo bem e não quero desativar o carregamento lento.
Mais tarde, porém, preciso enviar alguns dos objetos (na verdade um objeto) para o cliente GWT via RPC. E acontece que esse objeto concreto é um proxy. Então, eu preciso transformá-lo em um objeto real. Não consigo encontrar um método como "materializar" no Hibernate.
Como posso transformar alguns objetos de proxies em reais sabendo sua classe e ID?
No momento, a única solução que vejo é despejar esse objeto do cache do Hibernate e recarregá-lo, mas é muito ruim por vários motivos.
HibernateProxy
define umwriteReplace
método para forçar os implementadores a fazer algo especial durante a serialização.(T)Hibernate.unproxy(entity)
Como expliquei neste artigo , desde o Hibernate ORM 5.2.10 , você pode fazer o seguinte:
Antes do Hibernate 5.2.10 . a maneira mais simples de fazer isso era usar o método não- oxigenado oferecido pela
PersistenceContext
implementação interna do Hibernate :fonte
Department
lista comStudent
, ainda precisaunproxy(department.getStudents())
- ou é suficienteunproxy(department)
?PersistentContext#unproxy(proxy)
lança uma exceção se o proxy não for inicializado enquantoHibernate.unproxy(proxy)
e,LazyInitializer#getImplementation(proxy)
se necessário, inicialize o proxy. Só peguei uma exceção devido a essa diferença. ;-)Tente usar
Hibernate.getClass(obj)
fonte
Eu escrevi o seguinte código que limpa o objeto de proxies (se eles ainda não estiverem inicializados)
Eu uso essa função sobre o resultado dos meus serviços RPC (por meio de aspectos) e limpa recursivamente todos os objetos de resultado dos proxies (se não forem inicializados).
fonte
Da maneira que eu recomendo com o JPA 2:
fonte
Com o Spring Data JPA e o Hibernate, eu estava usando subinterfaces de
JpaRepository
para pesquisar objetos pertencentes a uma hierarquia de tipos que foi mapeada usando a estratégia "join". Infelizmente, as consultas estavam retornando proxies do tipo base em vez de instâncias dos tipos concretos esperados. Isso me impediu de transmitir os resultados para os tipos corretos. Como você, eu vim aqui procurando uma maneira eficaz de fazer com que minhas entidades não sejam afetadas.Vlad tem a idéia certa para desestabilizar esses resultados; Yannis fornece um pouco mais de detalhes. Além das respostas, aqui está o restante do que você pode estar procurando:
O código a seguir fornece uma maneira fácil de desoxirar suas entidades com proxy:
Você pode transmitir entidades não-autorizadas ou entidades com proxy para o
unproxy
método. Se eles já estiverem sem toxina, eles simplesmente serão devolvidos. Caso contrário, eles ficarão sem proteção e retornados.Espero que isto ajude!
fonte
A outra solução alternativa é chamar
Pouco antes de fechar a sessão.
fonte
Encontrei uma solução para deproxy uma classe usando API Java e JPA padrão. Testado com hibernação, mas não requer hibernação como uma dependência e deve funcionar com todos os provedores de JPA.
Um único requisito - é necessário modificar a classe pai (Endereço) e adicionar um método auxiliar simples.
Ideia geral: adicione o método auxiliar à classe pai que retorna automaticamente. Quando o método é chamado no proxy, ele encaminhará a chamada para a instância real e retornará essa instância real.
A implementação é um pouco mais complexa, pois o hibernate reconhece que a classe em proxy retorna a si mesma e ainda retorna o proxy em vez da instância real. A solução alternativa é agrupar a instância retornada em uma classe de wrapper simples, que possui um tipo de classe diferente da instância real.
Em código:
Para converter o proxy de endereço na subclasse real, use o seguinte:
fonte
A partir do Hiebrnate 5.2.10, você pode usar o método Hibernate.proxy para converter um proxy em sua entidade real:
fonte
Obrigado pelas soluções sugeridas! Infelizmente, nenhum deles funcionou para o meu caso: receber uma lista de objetos CLOB do banco de dados Oracle por meio do JPA - Hibernate, usando uma consulta nativa.
Todas as abordagens propostas me deram um ClassCastException ou apenas retornaram o objeto java Proxy (que continha profundamente o Clob desejado).
Portanto, minha solução é a seguinte (com base nas várias abordagens acima):
Espero que isso ajude alguém!
fonte