Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Trazer relacionamentos padrão eager como lazy

Olá, quando temos um relacionamento @OneToOne ele é EAGER por defalult, assim como propriedades simples mapeadas com @Column, entretanto, as vezes quero fazer com que estes relacionamentos eager sejam tragos como LAZY, mas mesmo anotando o relacionamento como lazy ele traz o relacionamento carregado, como fazer para que o JPA obedeça a anotação Lazy nestes casos?

3 respostas

Oi Ricardo,

pelo que sei, apenas relacionamentos @OneToOne com optional=false podem ser carregados Lazy.

Se o seu relacionamento sempre existe, coloque então:

@OneToOne(optional = false, fetch = FetchType.LAZY)

Sem optional = false realmente não dá, pois o hibernate não pode criar aquele proxy por baixo dos panos, e precisa verificar na hora se o relacionamento existe ou não.

abs, Nico

faz um tempo tive que implementar um diário oficial, onde eu guardava o texto no banco de dados em um campo tipo Long(Oracle 8i), precisava trazer essa string de forma lazy, na época pedi ajuda em foruns, e só me disseram para eu utilizar "instrumentação" que eu resolveria o problema, eu só não sei oque é essa tal de instrumentação, oque seria isso?

solução!

Oi Ricardo, tudo bem?

Quando o Hibernate implementa o Lazy Load das coleções ele usa uma subclasse da coleção que você usa no seu relacionamento, que buscará o relacionamento ao chamar algum método dessa subclasse (size, iterator, etc). Essa subclasse dele é o que chamamos de proxy. Ao trabalhar com Strings o hibernate perde esse controle e irá precisar alterar o Bytecode da classe String pra poder inserir o comportamento Lazy (isso é instrumentação).

Uma alternativa seria implementar a interface FieldHandled e criar seu próprio proxy. Por exemplo:

@Basic(fetch=FetchType.LAZY)
public String getNome() {
    if(handler != null)
        return (String) this.handler.readObject(this, "nome", nome);
    return nome;
}

Abraços!