Hibernate ~ mas um pouco e chuto o balde!

24 respostas
T

Nobres colegas,

Estou desenvolvendo um projeto utilizando Struts + Hibernate, este não contem nada de especial, apenas alguns cadastros. Porem venho encontrando a cada dia uma série de complicações na utilização do hibernate. Acredito que isto ocorra por EU estar complicando a arquitetura, espero que vc’s possam iluminar meus pensamentos e me ajudar a não desistir dele :smiley:

:arrow: Meu maior problema tem sido com Sessions do hibernate. Em um primeiro momento para cada consulta e/ou transação eu abria e encerrava uma Session. Isso funcionou até que me deparei com objetos utilizando lazy, os quais quando iam ser exibidos na camada de visão (JSP) recebia um LazyInitializationException devido a Session ter sido fechada. Segundo li em alguns textos utilizar lazy=“false” causa uma grande perca de performance do hibernate e não seria um boa solução. Procurando por outra solução me deparei com Open Session In View (OSIV).

POREM utilizando o OSIV me deparei com um outro problema:
:arrow: Quando por ex. seleciono um registro para editar, a action carrega ele sem problemas, mas quando vai coloca-lo no escopo de request com método setAttribute para ser editado em um JSP, este faz uma cópia do objeto só que não como proxy, e sim como um objeto não instanciado com valores nulos, invés de por uma referência para o endereço de memória do objeto recuperado pelo hibernate.

:?: Minha classe HibernateUtil, da qual eu solicito as Sessions esta utilizando ThreadLocal segundo li em um post aqui no GUJ é citado um problema entre ThreadLocals e Request, mas não vi uma explicação para tal ocorrer.

:?: ThreadLocal & OSIV, pelo oque estive pesquisando são duas soluções diferentes para gerênciar Session, contudo eu deveria estar utilizando uma ou outra e não ambas juntas, correto ?

24 Respostas

M

Se ele tá fazendo isso, não tem nada haver com o Hibernate, provavelmente é algum erro do seu código.

T

Cometer um erro em um método com dos atributos ? :wink:

M

tralala:
Cometer um erro em um método com dos atributos ? :wink:

:?:

C

tralala,

Eu acho dificil eu resolver seu problema, mas pela conversa parece que tive o mesmo problema e consegui sair dessa.
Faz o seguinte…

Coloca aí teus arquivos de mapeamento hbm.xml e o de configuração cfg.xml

Eu também tô puto com Hibernate + Struts mas num vou parar não.

M

Eu no seu lugar reconsideraria essas palavras :lol:

T

Cocota,

hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="localizacao" schema="sigv">

  <class name="Localizacao">

    <id name="codLocalizacao">
      <generator class="sequence">
        <param name="sequence">codlocalizacao_seq</param>
      </generator>
    </id>

    <property name="numero"/>
    <property name="complemento"/>

    <many-to-one name="localizacaoBase" column="localizacaobasecod" unique="true" cascade="save-update" />

  </class>

</hibernate-mapping>

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

  <session-factory>
    <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>

    <!-- Database connection settings -->
    <property name="connection.driver_class">org.postgresql.Driver</property>


    <property name="connection.url">jdbc:postgresql://localhost:5432/javasoft</property>
    <property name="connection.username">...</property>
    <property name="connection.password">...</property>


    <property name="show_sql">true</property>

<!--
    <property name="c3p0.acquire_increment">1</property>
    <property name="c3p0.min_size">10</property>
    <property name="c3p0.max_size">20</property>
    <property name="c3p0.timeout">300</property>
    <property name="c3p0.max_statements">50</property>
    <property name="c3p0.idle_test_period">3000</property>
-->
    <mapping resource="dao/map/AreaAcao.hbm.xml"/>
    <mapping resource="dao/map/Cliente.hbm.xml"/>
    <mapping resource="dao/map/ClienteConcorrente.hbm.xml"/>
    <mapping resource="dao/map/ClienteContato.hbm.xml"/>
    <mapping resource="dao/map/Empresa.hbm.xml"/>
    <mapping resource="dao/map/EmpresaAcesso.hbm.xml"/>
    <mapping resource="dao/map/EmpresaFuncionario.hbm.xml"/>
    <mapping resource="dao/map/Equipe.hbm.xml"/>
    <mapping resource="dao/map/Localizacao.hbm.xml"/>
    <mapping resource="dao/map/LocalizacaoBase.hbm.xml"/>
    <mapping resource="dao/map/Meta.hbm.xml"/>
    <mapping resource="dao/map/Produto.hbm.xml"/>
    <mapping resource="dao/map/ProdutoPublicoAlvo.hbm.xml"/>
    <mapping resource="dao/map/Venda.hbm.xml"/>
    <mapping resource="dao/map/VendaProduto.hbm.xml"/>
    <mapping resource="dao/map/Vendedor.hbm.xml"/>
    <mapping resource="dao/map/Visita.hbm.xml"/>
    <mapping resource="dao/map/VisitaOcorrencia.hbm.xml"/>

  </session-factory>

</hibernate-configuration>
S

Cocota:
Eu também tô puto com Hibernate + Struts mas num vou parar não.

Hibernate não é algo que vc domina em pouco tempo. Tem muito detalhizinho que pega. Claro que Hibernate é Hibernate e dispensa comentários, mas eu ainda prefiro ir de DAO, pois pra mim JDBC é mais fácil que Hibernate.

Struts melhor vc esquecer mesmo. Já está na hora…

Esse negócio de Lazy é pentelho… Eu prefiro controlar isso na munheca do que deixar o Hibernate controlar isso pra mim.

T

Maurício Linhares:
tralala:
Cometer um erro em um método com dos atributos ? :wink:

:?:

Explicando melhor:
Eu preciso exibir os dados de determinado objeto em um JSP, ok ?
Eu faço um get() deste sem problemas (debugando isso vejo que esta td certo) e que este aloca um endereço de memória x. Porem eu preciso repassar este para a camada de Visão, contudo faço um:

servletRequest.settribute("chave", objetoCarregadoPeloHibernate);

No JSP quando eu faço tento acessar o objeto, eu notei que ele estava mais em um endereço de memória X e sim Y, e que não era mais um proxy, e sim um objeto comum vazio e sem dados.

:arrow: O que quiz dizer em errar um método com 2 atributos, é que eu debugei o objeto antes de executar o método e vi que ele foi carregado corretamente, mas nessa transição de setar e recuperar ocorre uma mudança neste :slight_smile:

R

saoj:
Cocota:
Eu também tô puto com Hibernate + Struts mas num vou parar não.

Hibernate não é algo que vc domina em pouco tempo. Tem muito detalhizinho que pega. Claro que Hibernate é Hibernate e dispensa comentários, mas eu ainda prefiro ir de DAO, pois pra mim JDBC é mais fácil que Hibernate.

Struts melhor vc esquecer mesmo. Já está na hora…

Esse negócio de Lazy é pentelho… Eu prefiro controlar isso na munheca do que deixar o Hibernate controlar isso pra mim.

Grande Sergio,

Longe de mim querer critica-ló, mas esses frameworks todos vieram para facilitar a vida, mesmo assim vc prefere fazer tudo na munheca ?!

Vc faz isso para ter maior controle ?

Abraços

M

Use o Spring, e deixe ele controlar para vc :smiley:

C

Tu já deu uma olhada nesse tutorial?

Tutorial

Lá perto do fim, tem um Box que fala sobre o tal do Lazyloading.
Lá você escolhe o que usar. Eu resolvi esse problema usando outer-join no arquivo de mapeamento.
E habilitando ele no arquivo de configuração.

no outer-join você já traz os objetos tudo “pregado”. Aí usa eles.

Já o problema com os objetos nulos estava aparecendo quando eu tentava salvar o objeto. No arquivo de mapeamento tinham algumas property definida como not null. E dava problema direto. Aí eu tirei essa opção e resolveu.

T

saoj:
Cocota:
Eu também tô puto com Hibernate + Struts mas num vou parar não.

Hibernate não é algo que vc domina em pouco tempo. Tem muito detalhizinho que pega. Claro que Hibernate é Hibernate e dispensa comentários, mas eu ainda prefiro ir de DAO, pois pra mim JDBC é mais fácil que Hibernate.

Struts melhor vc esquecer mesmo. Já está na hora…

Esse negócio de Lazy é pentelho… Eu prefiro controlar isso na munheca do que deixar o Hibernate controlar isso pra mim.

Sergio,

Realmente o hibernate não é algo de se dominar da noite pro dia. Em relação ao struts concordo com vc mas no momento tenho outros empecilhos que me limitam a ele mas cá entre nós estudo um futura migração pro menta :thumbup:.

O lance do lazy é eu to insistindo pq acredito que se td mundo usa ele e fez funcionar não é possível que não vai funcionar comigo :smiley: hhehe. Mas em ultima instância vai ser uma opção :roll:

T

Cocota:
Tu já deu uma olhada nesse tutorial?

Tutorial

Lá perto do fim, tem um Box que fala sobre o tal do Lazyloading.
Lá você escolhe o que usar. Eu resolvi esse problema usando outer-join no arquivo de mapeamento.
E habilitando ele no arquivo de configuração.

no outer-join você já traz os objetos tudo “pregado”. Aí usa eles.

Este pregado vc diz, trazer eles como objeto concretos e não como proxy. Seria a mesma coisa de por um lazy=“false”, não ?

S

Hibernate é muito bom, e para um sistema parrudo com várias tabelas e vários esquemas de acesso ao banco de dados não tenho dúvida que ele vai te economizar um tempo, nem que seja na feitura dos SQLs, que vc não vai precisar fazer.

O problema é: o tiro vai sair pela culatra, se vc, como eu e provavelmente como o nosso amigo aqui do post, não dominar o Hibernate. O Hibernate tem muitos detalhes e várias sacanagens que vão atrasar os mais desavisados.

Como eu programo com JDBC, SQL, etc. há muito tempo, então pra mim é 10 vezes mais rápido usar isso do que Hibernate.

DAO é uma abordagem bem legal, usada a anos. Sugiro que vc baixe o código da aplicação mybooks e dê uma olhada em como eu faço o acesso a banco com DAO + IoC: http://www.mentaframework.org/mybooks.jsp

É questão de gosto e projeto. Hibernate ou DAO, eis a questão. Eu vou de DAO, pois já estou acostumado com isso. Se vc manja pouco ou nada de SQL, JDBC, cache, etc, então melhor ir de Hibernate mesmo…

Usar Hibernate por causa de Lazy Loading acho bobeira. Já usá-lo por causa do cache interno dele, de repente é uma boa.

Alguém que manja bem DAO e Hibernate poderia dar mais explicações sobre vantagens e desvantagens…

C

tralala:

Este pregado vc diz, trazer eles como objeto concretos e não como proxy. Seria a mesma coisa de por um lazy=“false”, não ?

Sim.
Então já era, can’t help anymore.

T

Cocota:
tralala:

Este pregado vc diz, trazer eles como objeto concretos e não como proxy. Seria a mesma coisa de por um lazy=“false”, não ?

Sim.
Então já era, can’t help anymore.

Tkz pela ajuda amigo :slight_smile:
Mas me diga, qual foi o seu problema ? Foi com lazy tb ?

[s]

M

tralala:

servletRequest.settribute("chave", objetoCarregadoPeloHibernate);

No JSP quando eu faço tento acessar o objeto, eu notei que ele estava mais em um endereço de memória X e sim Y, e que não era mais um proxy, e sim um objeto comum vazio e sem dados.

:arrow: O que quiz dizer em errar um método com 2 atributos, é que eu debugei o objeto antes de executar o método e vi que ele foi carregado corretamente, mas nessa transição de setar e recuperar ocorre uma mudança neste :slight_smile:

Você tem certeza de que esse “objetoCarregadoPeloHibernate” é o mesmo objeto que veio do get()?

Em Java não existem ponteiros, então é impossível trocar a “referência” ao objeto, a não ser que você tenha trocado ela e passado a referência errada em algum lugar (já que você disse que o Hibernate está fazendo o get() corretamente).

T

Obrigado por sua atenção Maurício,

Então antes de dar o setAttribute(), eu fiz que com fosse impresso os dados de algumas propriedades do objeto e vi que ele carregou certinho. Depois disso a unica coisa que fiz foi dar o set. Se achar nescessário envio o código fonte.

Ah eu não disse que ele trocou a referência, e sim que fez clone… Pois ele aloca outro endereço de memória.

T

Ah eu não disse que ele trocou a referência, e sim que fez clone… Pois ele aloca outro endereço de memória.

M

Quem fez clone(), o setAttribute()?

Se ele tivesse feito isso, você ia ver uma UnsupportedOperationException, porque se você chamar clone() em um objeto que não implementou o método clone() (ou a interface Cloneable), por default, a implementação de Object lança essa exceção.

Olhe direito o seu código aí que tem alguma coisa muito estranha.

T

Não estou dizendo o método clone() que é herdado da java.lang.Object

Quando me refiro a CLONE me refiro de uma forma mais abstrata, como por ex. utilizando um copyProperties do BeanUtils, poe ex.

M

Muito bom este tópico …

Não quero desmerecer nenhum framework nem criticar ninguém, mas cada framework do mercado tem suas vantagens e seus adeptos … Eu utilizo o struts a uns 2 anos. Isso me fez ter mta experiência nele … nas configurações chatas dos xml’s … Já o hibernate, eu tenho uns 8 meses de contato, mas com mta dedicação … em minhas aplicações eu já dispenso os xml’s da vida … não utilizo nenhum para config. do hibernate. Prá falar verdade, minhas aplicações tem 3 xml’s no total q são os da configuração do struts, web.xlm e validator.xml.

O hibernate sem dúvida alguma gera um ganho de produtividade mto grande em relação aos outros métodos de persistência de dados, mas como outro amigo disse, para aplicações de grande porte com mtas tabelas e entidades relacionais.

Eu utilizo o hibernate juntamente com o Patern DAO … dá prá imaginar a coisa linda que fica … tenho um ganho de produtividade mto grande utilizando tb Annotations, que me possibilita a não criação dos mapeamentos xml de cada entidade relacional.

Tá certo que para utilizar cada framework e patern aqui descrito tendo o seu máximo em produtividade e desempenho é preciso mta dedicação no estudo … eu tenho me dedicado nos últimos dias em especial no hibernate, e tenho certeza q não irei me arrepender, pois seja com o struts ou qq outro framework, ele sempre irá me gerar um ganho de produtividade.

Espero no futuro estar tendo a oportunidade de estudar outros frameworks, e já tenho entre alguns citados aqui o VRaptor como candidato.

[ :smiley: ]

M

tralala:
Não estou dizendo o método clone() que é herdado da java.lang.Object

Quando me refiro a CLONE me refiro de uma forma mais abstrata, como por ex. utilizando um copyProperties do BeanUtils, poe ex.

Não vou dizer que é impossível, porque sempre pode ser um bug desconhecido, mas o seu problema é extremamente esquisito, realmente não sei o que fazer :shock:

T

Maurício Linhares:
tralala:
Não estou dizendo o método clone() que é herdado da java.lang.Object

Quando me refiro a CLONE me refiro de uma forma mais abstrata, como por ex. utilizando um copyProperties do BeanUtils, poe ex.

Não vou dizer que é impossível, porque sempre pode ser um bug desconhecido, mas o seu problema é extremamente esquisito, realmente não sei o que fazer :shock:

Hehehhe pois é!
Tipo vou ver se monto um WAR exemplificando oque ta acontencendo aqui pra galera poder ver melhor.

Criado 18 de abril de 2006
Ultima resposta 18 de abr. de 2006
Respostas 24
Participantes 7