Problema Hibernate

4 respostas
W

Olá pessoal, tô precisando de uma ajudinha aqui no Hibernate, olha só:
Dois objetos, um chamado Sistema e outro MenuSistema, sendo que um Sistema tem de 1 a N MenuSistema. (Estou usando o Oracle 10g)

Aqui está o mapeamento de Sistema.hbm.xml:

<hibernate-mapping>
    <class 
        name="gov.ce.ipmfor.model.sca.Sistema" 
        table="SISTEMA">
      <id name="codigo" column="CODIGO" type="int" unsaved-value="-1">         
		 <generator class="sequence">			
           <param name="sequence">SISTEMA_SEQ</param>
         </generator>		 
      </id>
	  <set name="menusistema" lazy="true" table="MENU_SISTEMA" inverse="true" cascade="all">
		<key column="sistema">
		   <!--column name="sistema"></column-->						
		</key>
		<one-to-many class="gov.ce.ipmfor.model.sca.MenuSistema"/>
	  </set>
      <property name="nome" column="NOME"/>
      <property name="descricao" column="COMENTARIO"/>
      <property name="status" column="SITUACAO"/>
      <property name="link" column="LINK"/>  	  
   </class>    
</hibernate-mapping>

Aqui o mapeamento de MenuSistema.hbm.xml

<hibernate-mapping>
	<class 
		name="gov.ce.ipmfor.model.sca.MenuSistema" 
		table="MENU_SISTEMA">
		<id name="codigo" column="CODIGO" type="int" unsaved-value="-1">
			<generator class="sequence">
           <param name="sequence">MENU_SISTEMA_SEQ</param>
         </generator>			
		</id>
		<many-to-one name="sistema"  
			column="SISTEMA" 
			not-null="true" 
			cascade="save-update" 
			class="gov.ce.ipmfor.model.sca.Sistema" 
			unique="true">
		</many-to-one>
		<!--property name="sistema" column="SISTEMA"/-->
		<property name="nome" column="DESCRICAO"/>	
		<property name="link" column="LINK"/>	
        <property name="situacao" column="SITUACAO"/> 		
	</class>
</hibernate-mapping>

Aqui um Trecho do meu arquivo SistemaDAO.java:

...
Sistema s = new Sistema();
List sistemas = new ArrayList(); 
Criteria criteria = (Criteria) session.createCriteria(s.getClass()).addOrder(Order.asc("nome"))
            .setFirstResult(0)
            .setMaxResults(10);
            sistemas = criteria.list();
            //teste com a listagem de sistemas
            if (sistemas.size() != 0) {
                for (Iterator i = sistemas.iterator(); i.hasNext();){
                    s = (Sistema) i.next();
                    System.out.println("sistema: "+ s.getNome());
                    Set menu = (Set) s.getMenuSistema();
                    if (menu != null) {
                        if (menu.size() != 0) {
                            for (Iterator iter = menu.iterator(); iter.hasNext();){
                                if (iter.next() instanceof MenuSistema){
                                    System.out.println("menu: "+((MenuSistema) i.next()).getNome());//é aqui onde dispara a exceção
                                }
                            }
                        } else {
                            System.out.println("sistema não tem menus");
                        }
                    }
                }
            }

Olha só o que acontece:

Hibernate: select * from ( select this_.CODIGO as CODIGO0_, this_.NOME as NOME6_0_, this_.COMENTARIO as COMENTARIO6_0_, this_.SITUACAO as SITUACAO6_0_, this_.LINK as LINK6_0_ from SISTEMA this_ order by this_.NOME asc ) where rownum <= ?
sistema: Almoxarifado
Hibernate: select menusistem0_.sistema as sistema1_, menusistem0_.CODIGO as CODIGO1_, menusistem0_.CODIGO as CODIGO0_, menusistem0_.SISTEMA as SISTEMA7_0_, menusistem0_.DESCRICAO as DESCRICAO7_0_, menusistem0_.LINK as LINK7_0_, menusistem0_.SITUACAO as SITUACAO7_0_ from MENU_SISTEMA menusistem0_ where menusistem0_.sistema=?
sistema não tem menus
sistema: Previdência
Hibernate: select menusistem0_.sistema as sistema1_, menusistem0_.CODIGO as CODIGO1_, menusistem0_.CODIGO as CODIGO0_, menusistem0_.SISTEMA as SISTEMA7_0_, menusistem0_.DESCRICAO as DESCRICAO7_0_, menusistem0_.LINK as LINK7_0_, menusistem0_.SITUACAO as SITUACAO7_0_ from MENU_SISTEMA menusistem0_ where menusistem0_.sistema=?
sistema não tem menus
sistema: Recursos Humanos
Hibernate: select menusistem0_.sistema as sistema1_, menusistem0_.CODIGO as CODIGO1_, menusistem0_.CODIGO as CODIGO0_, menusistem0_.SISTEMA as SISTEMA7_0_, menusistem0_.DESCRICAO as DESCRICAO7_0_, menusistem0_.LINK as LINK7_0_, menusistem0_.SITUACAO as SITUACAO7_0_ from MENU_SISTEMA menusistem0_ where menusistem0_.sistema=?
sistema não tem menus
sistema: Saúde
Hibernate: select menusistem0_.sistema as sistema1_, menusistem0_.CODIGO as CODIGO1_, menusistem0_.CODIGO as CODIGO0_, menusistem0_.SISTEMA as SISTEMA7_0_, menusistem0_.DESCRICAO as DESCRICAO7_0_, menusistem0_.LINK as LINK7_0_, menusistem0_.SITUACAO as SITUACAO7_0_ from MENU_SISTEMA menusistem0_ where menusistem0_.sistema=?
sistema não tem menus
sistema: Suporte
Hibernate: select menusistem0_.sistema as sistema1_, menusistem0_.CODIGO as CODIGO1_, menusistem0_.CODIGO as CODIGO0_, menusistem0_.SISTEMA as SISTEMA7_0_, menusistem0_.DESCRICAO as DESCRICAO7_0_, menusistem0_.LINK as LINK7_0_, menusistem0_.SITUACAO as SITUACAO7_0_ from MENU_SISTEMA menusistem0_ where menusistem0_.sistema=?
(hibernate.LazyInitializationException 19  ) illegal access to loading collection
org.hibernate.LazyInitializationException: illegal access to loading collection
	at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:172)
	at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:48)
	at org.hibernate.collection.PersistentSet.hashCode(PersistentSet.java:324)
	at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:392)
	at org.apache.commons.lang.builder.HashCodeBuilder.reflectionAppend(HashCodeBuilder.java:353)
	at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:327)
	at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:194)
	at gov.ce.ipmfor.model.sca.BaseObject.hashCode(BaseObject.java:27)
	at gov.ce.ipmfor.model.sca.Sistema.hashCode(Sistema.java:144)
	at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:392)
	at org.apache.commons.lang.builder.HashCodeBuilder.reflectionAppend(HashCodeBuilder.java:353)
	at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:327)
	at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:194)
	at gov.ce.ipmfor.model.sca.BaseObject.hashCode(BaseObject.java:27)
	at gov.ce.ipmfor.model.sca.MenuSistema.hashCode(MenuSistema.java:131)
	at java.util.HashMap.put(Unknown Source)
	at java.util.HashSet.add(Unknown Source)
	at java.util.AbstractCollection.addAll(Unknown Source)
	at org.hibernate.collection.PersistentSet.endRead(PersistentSet.java:242)
	at org.hibernate.engine.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:183)
	at org.hibernate.engine.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:268)
	at org.hibernate.engine.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:249)
	at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:554)
	at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:541)
	at org.hibernate.loader.Loader.doQuery(Loader.java:436)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:218)
	at org.hibernate.loader.Loader.loadCollection(Loader.java:1434)
	at org.hibernate.loader.collection.OneToManyLoader.initialize(OneToManyLoader.java:111)
	at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:488)
	at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
	at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1430)
	at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:176)
	at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:48)
	at org.hibernate.collection.PersistentSet.size(PersistentSet.java:110)
	at gov.ce.ipmfor.dao.sca.SistemaDAO.getListBeans(SistemaDAO.java:95)
	at gov.ce.ipmfor.delegate.sca.SistemaDelegate.getListaSistemas(SistemaDelegate.java:120)
	at gov.ce.ipmfor.delegate.sca.SistemaDelegate.<init>(SistemaDelegate.java:60)
	at gov.ce.ipmfor.service.sca.loadListaSistemas.perform(loadListaSistemas.java:42)
	at org.apache.struts.action.ActionServlet.processActionPerform(ActionServlet.java:1619)
	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1429)
	at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:462)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
	at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:118)
	at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
	at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
	at java.lang.Thread.run(Unknown Source)

Alguém pode me dar uma ajudinha aí? Agradeço antecipadamente a atenção.

Wagner

(“O Senhor é bom e a sua misericórdia dura para sempre”)

4 Respostas

W

Estou fazendo uma pequena correção no SistemaDAO.java

... 
Sistema s = new Sistema(); 
List sistemas = new ArrayList(); 
Criteria criteria = (Criteria) session.createCriteria(s.getClass()).addOrder(Order.asc("nome")) 
            .setFirstResult(0) 
            .setMaxResults(10); 
            sistemas = criteria.list(); 
            //teste com a listagem de sistemas 
            if (sistemas.size() != 0) { 
                for (Iterator i = sistemas.iterator(); i.hasNext();){ 
                    s = (Sistema) i.next(); 
                    System.out.println("sistema: "+ s.getNome()); 
                    Set menu = (Set) s.getMenuSistema(); 
                    if (menu != null) { 
                        if (menu.size() != 0) { 
                            for (Iterator iter = menu.iterator(); iter.hasNext();){ 
                                if (iter.next() instanceof MenuSistema){ 
                                    System.out.println("menu: "+((MenuSistema) iter.next()).getNome());//CORREÇÃO                                } 
                            } 
                        } else { 
                            System.out.println("sistema não tem menus"); 
                        } 
                    } 
                } 
            }

Mesmo assim o erro persiste.

Wagner

P

o problema esta aqui:

<set name="menusistema" lazy="true" table="MENU_SISTEMA" inverse="true" cascade="all"> <key column="sistema"> <!--column name="sistema"></column--> </key> <one-to-many class="gov.ce.ipmfor.model.sca.MenuSistema"/> </set>

mude para:

<set name="menusistema" lazy="false" table="MENU_SISTEMA" inverse="true" cascade="all"> <key column="sistema"> <!--column name="sistema"></column--> </key> <one-to-many class="gov.ce.ipmfor.model.sca.MenuSistema"/> </set>

mudamos o parametro “lazy” para false, assim quando vc carregar o seu objeto Sistema ele vai inicializar a colection automaticamente…mas tome cuidado, pq usar isso em varios lugares do seu mapeamento pode prejudicar muito a performance…

uma outra alterantiva é vc inicializar a colection sobre demanda…procure o metodo initialize() da classe Hibernate…

espero ter ajudado…

W

Valeu, cara…

Mas dentro dessa mesma abordagem, ainda tenho algumas dúvidas…

Suponha que eu crie uma instância de SistemaDAO em outra classe. Por exemplo:

...
  SistemaDAO sistemaDAO = new SistemaDAO();
  Sistema s = new Sistema();
  s = (Sistema) sistemaDAO.getBean(s.getCodigo());
  System.out.println("Nome do sistema é: "+ s.getNome());
  //até aqui tudo bem, mas na próxima instrução vai ocorrer uma exceção
  Set menusDesseSistema  = (Set) s.getMenuSistema();
  ...

Isso acontece por que a função getBeans(int id) de sistemaDAO, vai nessa ordem:

  • abrir uma Session do Hibernate;
  • iniciar uma Transaction;
  • recuperar um Sistema de código s.getCodigo();
  • fechar a Transaction.

Ou seja, mesmo que a referência ao Set esteja em sistema, ele não vai carregar o conjunto de menus, visto que não não há sessão aberta.

Foi aí que eu pensei em criar outro DAO só para carregar um objeto da classe MenuSistema, assim:

...
  SistemaDAO sistemaDAO = new SistemaDAO();
  Sistema s = new Sistema();
  s = (Sistema) sistemaDAO.getBean(s.getCodigo());
  MenuSistemaDAO menuDAO = new MenuSistemaDAO():
  Set menusDesseSistema  = (Set) menuDAO.getMenuSistema(s); //essa função recebe um objeto do tipo Sistema como parâmetro 
  ...

Gostaria de saber se essa mudança de estratégia seria correta. Se há uma melhor, agradeço antecipadamente se puder ajudar.

P

se vc setar o lazy como false, independente do seu controle transacional, vai funcionar…pq o Set eh inicializado sempre q vc popular a classe Sistema com os dados do banco…

Criado 10 de novembro de 2006
Ultima resposta 16 de nov. de 2006
Respostas 4
Participantes 2