Hibernate Fetch Select ou Join - hbm p/ annotations
7 respostas
romuloff
Na minha aplicação quero que um objeto aninhado se “auto-popule” (baseado em seu ID/PK) quando eu salvar o objeto que aninha ele.
No caso da minha aplicação é assim:
meu Imposto tem um Estado. na hora de salvar Imposto só quero fazer ± assim:
"impostoTO.setEstadoTO(new Estado(12L));"
e assim que eu buscar esse imposto recem-salvo já virá com TODOS os atributos do Estado com id 12.
Quando eu utilizava hbm em outros projetos; o relativo que funcionava era assim:
ImpostoTO.hbm.xml: <many-to-one name="estadoTO" class="br.com.ctbc.avalia.model.data.EstadoTO" fetch="select" lazy="false">
<column name="ESTADO_ID" />
</many-to-one>
Mas no meu projeto atual estou utilizando annotations e tentei fazer assim:
ImpostoTO.java:import javax.persistence.ManyToOne;
import javax.persistence.JoinColumn;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
.
.
.
@ManyToOne( targetEntity = EstadoTO.class )
@JoinColumn( name = "ESTADO_ID", nullable = false )
@Fetch( FetchMode.SELECT )
public EstadoTO getEstadoTO() {
return estadoTO;
}
E não deu certo.
Não é um erro; mas continua vindo somente o id de EstadoTO nos ImpostoTO’s recem-salvos.
O mais estranho é que se eu reinicio o servidor aí vem tudo populado (como eu quero desde a hora que salva).
Tentei usar o flush no DAO do Imposto já que quando eu reinicio o servidor o resultado fica do jeito que quero (trazendo TODOS atributos de Estado).
[color=red]Mas tambem não deu certo.[/color]
alguem sabe o que falta ? um chute pelo menos ? nada ?
Gerson_da_S_Lima
@Fetch(FetchMode.JOIN)
acho que isso resolve
romuloff
Gerson da S. Lima:
@Fetch(FetchMode.JOIN)
acho que isso resolve
Tambem não funcionou com o JOIN
Já havia tentado e esqueci de comentar.
Ainda não é a solução ideal e nem a que eu estou procurando; [color=blue]//ALGUEM POR FAVOR ME DIZ O QUE FALTA PRO FETCH SELECT OU FETCH JOIN FUNCIONAR[/color]
mas achei uma um pouco menos feia do que a descrita anteriormente por mim:
ImpostoTO.java: //@LazyToOne( LazyToOneOption.FALSE )
//@Fetch( FetchMode.SELECT )
//@Fetch( FetchMode.JOIN )
@ManyToOne
@Cascade( CascadeType.REFRESH )
@JoinColumn( name = "ESTADO_ID", nullable = false )
public EstadoTO getEstadoTO() {
return estadoTO;
}ultima linha antes do retorno de ImpostoService.java/create()://refresh to load related entities
refresh( impostoTO );
Gerson_da_S_Lima
já esperimentou fazer isso:
@ManyToOne(fetch = FetchType.EAGER)
é equivalente no seu hbm.xml a lazy=“false”
só que o problema aqui é a performance, não sei se você já viu a diferença do lazy=“true” e lazy=“false”, se não posta aí que eu tento te explicar.
o melhor seria deixar o lazy=“true” e o trecho que eu descrevi acima como: @ManyToOne(fetch = FetchType.LAZY) e você carregar os relacionamentos que precisar.
romuloff
Gerson da S. Lima:
já esperimentou fazer isso:
@ManyToOne(fetch = FetchType.EAGER)
é equivalente no seu hbm.xml a lazy=“false”
só que o problema aqui é a performance, não sei se você já viu a diferença do lazy=“true” e lazy=“false”, se não posta aí que eu tento te explicar.
o melhor seria deixar o lazy=“true” e o trecho que eu descrevi acima como: @ManyToOne(fetch = FetchType.LAZY) e você carregar os relacionamentos que precisar.
Tambem não funcionou. Tentei o EAGER com o @Fetch( FetchMode.SELECT ) e com o FetchMode.JOIN
No caso do ManyToOne o lazy false não implica tanto em performance. Acontece mais no OneToMany ou quando o objeto aninhado (EstadoTO) é muito 'abrangente… que não é o caso.
Acabei de tentar colocando estas propriedades no hibernate.cfg.xml (tambem nao resolveu):
3
16
8
romuloff
Como ainda não resolveu pelo Fetch, mantive a solução do refresh. Mas fiz a alteração tirando o refresh do ImpostoService.java e passei pro DAO generico.
Engraçado que esse refresh funcionou do jeito que estava funcionando mesmo eu removendo o @Cascade( CascadeType.REFRESH ) do getEstadoTO ...
De qualquer forma ainda fica minha dúvida de como fazer isto funcionar com o Fetch.
I:
Ainda não é a solução ideal e nem a que eu estou procurando; [color=blue]//ALGUEM POR FAVOR ME DIZ O QUE FALTA PRO FETCH SELECT OU FETCH JOIN FUNCIONAR[/color]
Enfim, a solução provisória ficou assim:
AbstractHibernateDAO.create-ultima linha: