JPA + Hibernate - lazy loading

Pessoal,

Tenho uma classe com as segiuntes linhas:

	@Column(name="blbarquivo")
	@Basic(fetch=FetchType.LAZY)
	@Lob
	private byte[] arquivo;

Mas ao olhar a saída do show_sql=true no hibernate, percebi que ele está dando o select com o campo ‘blbarquivo’. Ou seja, o LAZY não está funcionando!
Ele deveria buscar esse campo no banco de dados apenas se eu acesso o getter getArquivo().

Alguem pode ajudar?

Obrigado.

ja tentou tirar a anotação do lazy, pra ver oque acontece ?

Buenas Guilherme,

Aqui na empresa tivemos problemas semelhantes com o lazy, pois usavamos o fetch=FetchType.LAZY em relacionamentos entre as tabelas e sempre eram carregadas as listas por exemplo.
Aqui resolvemos este problema utilizando a annotation @Proxy (org.hibernate.annotations.Proxy). Que vc teria q colocar na entidade.
Por exemplo:

@Entity
@Table(name = "CIDADAO")
@Proxy(lazy = true)
public class Cidadao implements Serializable{
//........

Somente após adicionar esta annotations, os “Fetch’s” passaram a funcionar.

Espero ter ajudado.

Tentei colocar o @Proxy mas não adiantou, continou aparecendo o campo no select.
Quanto a tentar tirar a annotation @Basic, não vejo proposito, vai ficar a todos os outros campos ^^

A pagina web está demorando muito para aparecer por causa desse campo, um absurdo! Preciso muito de uma resolução para isso…
Seria legal também ter umaa solução via JPA, que não precise colocar o Hibernate no meio, senão perde um pouco do propósito ^^

Obrigado mais uma vez…

o “fetchType” não ja vem lazy se não colocar a anotação ? deixe sem nenhuma anotação relacionada a isso, que eu acho que ele ja vem fazendo isso que voce ta querendo que ele faça.

Cara, dá uma pequisada, mas lembro que um tempo atrás um colega aqui profetizou algo
parecido com isso:

Agora, nunca fui atrás pra ver se isso é verdade ou não, sei que pra solucionar ele teve que
criar uma outra table e colocar o byte[] lá. Dai carrega somente quando precisava.

Se vc conseguir descobrir coloca a solução pra nós…

Depende do banco, i guess…

tentei fazer isso, não funfava…

Ai fiz um relacionamento mesmo… ai foi

Vou verificar se existe alguma resposta pra esse problema…
Se alguem souber de algo, por favor avise!!!

Agora, se eu precisar criar uma tabela a parte e um relacionamento para isso, ficarei decepcionado!!!

Obrigado!

Pois é, mas pensa pelo lado positivo, se vc separar vai criar outro conceito no teu modelo, o
Arquivo.
Se for o caso pode até reaproveitar em outras situações, colocar mais informações do arquivo, etc.

[quote=Guilherme Gomes]Vou verificar se existe alguma resposta pra esse problema…
Se alguem souber de algo, por favor avise!!!

Agora, se eu precisar criar uma tabela a parte e um relacionamento para isso, ficarei decepcionado!!!

Obrigado![/quote]

Eu não criei outra tabela…

Criei outro objeto…

A tabela é a mesma…

Porem tenho 2 objetos…

O primeiro mostra todas as propriedades, e tem uma conexão lazy com o segundo objeto…
O segundo so tem o ID e a propriedade que quero q venha lazy…

Apenas 1 tabela, dois objetos ^^

[quote=fabiofalci]Pois é, mas pensa pelo lado positivo, se vc separar vai criar outro conceito no teu modelo, o
Arquivo.
Se for o caso pode até reaproveitar em outras situações, colocar mais informações do arquivo, etc.[/quote]

Essa minha tabela já segue o conceito do arquivo ^^
Ela é reaproveitavel e muito bem centralizada. Essa tabela foi bem pensada antes de ser criada… No meu sistema, essa resolução é um ponto negativo.

cara eu uso aqui sem nenhum problema, eu não coloco nenhuma anotação nesse sentido, e ele se comporta como lazy SEMPRE!
talvez alguma entidade que não seja a que voce ta olhando que esteja como eager que esta carregando, ou até no própio ato de debugar voce pode está pedindo pra ele carregar ao clicar na coleção!
tire todos as anotações de lazy do seu código, todas as de eager, é assim que eu faço aqui, funciona sem problema algum…

[quote=sandroalm.silva]cara eu uso aqui sem nenhum problema, eu não coloco nenhuma anotação nesse sentido, e ele se comporta como lazy SEMPRE!
talvez alguma entidade que não seja a que voce ta olhando que esteja como eager que esta carregando, ou até no própio ato de debugar voce pode está pedindo pra ele carregar ao clicar na coleção!
tire todos as anotações de lazy do seu código, todas as de eager, é assim que eu faço aqui, funciona sem problema algum…
[/quote]

Então todos os campos, de todas as entidades que você usa que não são anotados com @Basic(fetch=…) ficam como LAZY? Não mesmo!

Tirado do proprio site do hibernate:

https://www.hibernate.org/398.html#A48

Lá está falando que funciona, mas não funciona ^^

por exemplo

[code]@Entity
@Table(“usuario”)
public class Usuario implements Serializable {
@Id
@GeneratedValue
private Integer id;
private String nome;
private …
@OneToOne(fetch=LAZY)
private UsuarioFoto foto;

}[/code]

@Entity @Table("usuario") public class UsuarioFoto { @Id private Integer id; private byte[] foto; }

Algo + ou - assim… não lembro 100%

[quote=Guilherme Gomes]
Tirado do proprio site do hibernate:

https://www.hibernate.org/398.html#A48

Lá está falando que funciona, mas não funciona ^^[/quote]

O problema guilherme, é que nem todo banco aceita… por exemplo, SQLServer isso não deu certo, meu livro EJB in Action também fala de usar fetch no basic… mais infelismente na pratica não deu certo =/

sim cara, sim mesmo, nunca usei essa anotação Basic, muito menos essa proxy… e volto a dizer que nunca tive problemas com isso.

Não sei, mas se for dependente de banco, só pra deixar registrado, tivemos esse comportamento
de trazer mesmo com Lazy no Sybase.

Não entendo como isso pode ser dependente do banco!

Vamos supor que essa seja a tabela:

Tabela arquivo
filename varchar(255)
dados blob

Deixar o blob lazy, forçaria o hibernate a iniciar a pesquisa como “select filename from arquivo” em vez de “select filename, dados from arquivo”. E depois ele faria a pesquisa pelo campo dados.
Do ponto de vista da aplicação, não deveria ser dependente do BD.

Eu realmente li por aí falando que só alguns bancos (como PostgreSQL) implementam o lazy loading de campos blob/clob. Não entendo o por que ^^

Uso MySQL 5.*

Embora haja o atributo fetch na anotação @Basic do JPA, lazy-load só é implementado para associações, e não para propriedades. As implementações JPA mais usadas que são Hibernate e Toplink/Eclipselink não implementam tal funcionalidade. Ou seja, não é exclusivo de lazy de blobs, mas lazy de qualquer propriedade.

Ou seja, você nunca vai conseguir fazer lazy-load de propriedades, mesmo que a spec diga que você pode. Não sei o real motivo de não ser implementado isso.

Uma sugestão: em um projeto meu possui uma classe chamada BinaryFile. Essa classe possui id, nome do arquivo, hash md5. O conteúdo do arquivo, no caso a propriedade que é lazy fica em outra classe associada via embeded. Ou seja, esse campo fica na mesma tabela, porém nas classes Java não.

É, olha esse post
https://forum.hibernate.org/viewtopic.php?t=962140

E a reposta do Emmanuel do hibernate.

*edit: como o garcia-jj apontou, é opcional.
Procure por “LOBs, BLOBs, CLOBs and Serialization” aqui http://en.wikibooks.org/wiki/Java_Persistence/Basic_Attributes