Mapeamento

15 respostas
R

Olá,
Não estou conseguindo fazer mais de um relacionamento. Aqui está o codigo:

...	
	@OneToMany(mappedBy = "usuario", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	private Collection<Endereco> enderecos = new ArrayList<Endereco>();
	
        //Este relacionamento  funciona se eu apagar o de cima, mas eu precisaria dos dois.
	@OneToMany(mappedBy = "usuario", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	private Collection<FormaDeContato> formaDeContatos = new ArrayList<FormaDeContato>();
...

Um só funciona se eu apagar o outro. É possivel fazer mais de um @OneToMany?
Obrigado

15 Respostas

Lavieri

é possivel sim, não há sentido de funcionar apenas um… o erro deve ser outra coisa, qual erro q da ?

rissato

isso dá um erro em função do tipo de coleção que vc tá usando. Tenta trocar Collection por List, ou Set…

R

Tentei com o List<> mas deu o mesmo erro.

erro:

Exception in thread main java.lang.NullPointerException

at br.com.stenovoice.dao.HibernateTransactionUtils.getSession(HibernateTransactionUtils.java:49)

at br.com.stenovoice.dao.HibernateCRUDUtils.getById(HibernateCRUDUtils.java:97)

at br.com.stenovoice.dao.BaseDAO.getByPrimaryKey(BaseDAO.java:37)

at br.com.stenovoice.teste.EnderecoTeste.main(EnderecoTeste.java:12)

Obrigado
Lavieri

e o que tem na linha 49 ?? que esta dando null ?

R

Lavieri, eu acho que o erro está no mapeamento pelo fato de que em todas as outras ações que faço não aparecerem erros.
Eu troquei o Collection pelo List e deu erro.
O engraçado é que se eu apago um dos relacionamentos o outro funciona.
Tanto no mapeamento endereco quanto no formaDeContato, uso o private Usuario usuario, não seria este o erro?

Lavieri

eu não posso dizer, sem ver o código do HibernateTransactionUtil

mais não faz sentido trirar uma das collections e o erro sumir… no meu caso especifico eu só uso “Set”, pois os elementos da minha lista não se repetem, mas acredito q isso não seja problema nenhum…

sua saida de erro, esta falando que getSession na linha 49 esta sendo NULL, e portanto é preciso olhar HibernateTransactionUtil, para saber o pq do erro

R
package br.com.stenovoice.dao;

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.stat.Statistics;

public class HibernateTransactionUtils {
	private static SessionFactory sessionFactory;
	
	private static Logger log = Logger.getLogger(HibernateTransactionUtils.class);;
	
	public HibernateTransactionUtils() {
		try {
			// Cria a instância da SessionFactory
			sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
			HibernateTransactionUtils.setSessionFactory(sessionFactory);
			
		} catch (Throwable ex) {
			// Não foi possível iniciar a SessionFactory - abortando a
			// inicialização da aplicação e logando o problema-
			log.fatal("\n\n\n\n\n\n\n>>>>>Criacao do SessionFactory falhou.\n" + ex);
			
		}	
	}
		
	/*
	 * Session Factory que gerencia as sessões do Hibernate
	 */
	private static final ThreadLocal<Session> tlSession = new ThreadLocal<Session> ();
	
		
	/**
	 * Método responsável por retornar uma sessão com o Hibernate 
	 * @return
	 * @throws HibernateException
	 */
	public static Session getSession() throws HibernateException {
        Session session = (Session) tlSession.get();
        
        // Abre uma nova session caso esta Thread não tenha uma vinculada
        if (session == null || !session.isOpen()) {
        	session = sessionFactory.openSession();

            // Armazena na variável ThreadLocal
            tlSession.set(session);
        }
        HibernateTransactionUtils.getSFStatistics();
        System.out.println("return");
        return session;
    }
	
	/**
	 * Método responsável por fechar uma conexão com o Hibernate
	 * @throws HibernateException
	 */
	public static void closeSession() throws HibernateException {
        Session s = (Session) tlSession.get();
        if (s != null)
            s.close();
        tlSession.set(null);
    }
	
	/**
	 * Retorna uma referência para a SessionFactory
	 * @return
	 */
    public static SessionFactory getSessionFactory( ) {
      return sessionFactory;
    }
    
    /**
	 * Configura um SessionFactory SessionFactory
	 * @return
	 */
    public static void setSessionFactory(SessionFactory factory) {
    	sessionFactory = factory;
    	sessionFactory.getStatistics().setStatisticsEnabled(true); //Estatísticas de performance do Hibernate.
    }

    
    /**
     * Método responsável por realizar um rollback na transação aberta pelo Hibernate
     * 
     * @param transaction
     */
    public static void rollback(Transaction transaction) {
        if (transaction != null) {
            try {
                transaction.rollback( );
            }
            catch (HibernateException ex) {
                // Logar e retornar a execução de um rollback;
            	log.debug(">>>>>Não foi possível realizar o rollback");
            }
        }
    }

    /**
     * Método responsável por realizar um commit na transação aberta pelo Hibernate
     * 
     * @param transaction
     */
    public static void commit(Transaction transaction) {
        if (transaction != null) {
            try {
                transaction.commit( );
            }
            catch (HibernateException ex) {
            	log.debug(">>>>>Não foi possível realizar o commit.");
            }
        }
    }
    
    public static Map<String, String> getSFStatistics() {
    	Statistics stats = sessionFactory.getStatistics();
    	HashMap<String, String> statMap = new HashMap<String, String>();
    	statMap.put("open_sessions", Long.toString(stats.getSessionOpenCount()));
    	System.out.println("\n\n>>>>>>>>>>>>>>>>>Open Sessions => " + statMap.get("open_sessions"));
    	return null;
    }

	public static Transaction getTransaction() {
		return null;
	}

}
rissato

confirma se vc acha esse erro no seu log:

Error connect to the database org.hibernate.HibernateException: cannot simultaneously fetch multiple bags

O fato de vc retirar uma das listas e o erro desaparecer pode estar relacionado com o erro acima. Nesse caso, a solução é como eu tinha dito acima: vc deve trocar o tipo das coleções (tente mudar pra Set também)

Lavieri

pelo seu HibernateTransactionUtil, o nullpointerException é pq a SessionFactory não foi criada, por isso da isso na linha 49…

lendo o seu código da pra ver que, entre as linhas 20 e 30, vc faz um try catch, e guarda o erro no log, mais continua o programa normalmente… e o erro deve ocorrer dentro desse try catch…

então abra o log, e veja o erro, ou adcione a linha 29 “ex.printStackTrace();” e cole aqui o erro

R

lavieri,
testei com o set e deu o seguinte resultado no console:

Hibernate: select usuario0_.id as id0_3_, usuario0_.criado as criado0_3_, usuario0_.demais_nome as demais3_0_3_, usuario0_.disponibiidade as disponib4_0_3_, usuario0_.disponibilidade as disponib5_0_3_, usuario0_.lista_disp_diario_arquivos as lista6_0_3_, usuario0_.lista_disp_diario_minutos as lista7_0_3_, usuario0_.lista_disp_total_arquivos as lista8_0_3_, usuario0_.lista_disp_total_minutos as lista9_0_3_, usuario0_.modificado as modificado0_3_, usuario0_.prefixo as prefixo0_3_, usuario0_.primeiro_nome as primeiro12_0_3_, usuario0_.qtde_arquivos as qtde13_0_3_, usuario0_.sufixo as sufixo0_3_, usuario0_.tamanho_maximo_arquivos as tamanho15_0_3_, usuario0_.tamanho_maximo_intervalo as tamanho16_0_3_, usuario0_.tamanho_maximo_minutos as tamanho17_0_3_, usuario0_.tat_maximo as tat18_0_3_, usuario0_.tipo as tipo0_3_, usuario0_.tipo_pessoa as tipo20_0_3_, usuario0_.tipo_usuario as tipo21_0_3_, usuario0_.ultimo_nome as ultimo22_0_3_, enderecos1_.usuario_id as usuario14_5_, enderecos1_.id as id5_, enderecos1_.id as id1_0_, enderecos1_.bairro as bairro1_0_, enderecos1_.cep as cep1_0_, enderecos1_.cidade as cidade1_0_, enderecos1_.complemento as compleme5_1_0_, enderecos1_.criado as criado1_0_, enderecos1_.endereco as endereco1_0_, enderecos1_.modificado as modificado1_0_, enderecos1_.numero as numero1_0_, enderecos1_.pais as pais1_0_, enderecos1_.principal as principal1_0_, enderecos1_.tipo_endereco as tipo12_1_0_, enderecos1_.uf as uf1_0_, enderecos1_.usuario_id as usuario14_1_0_, formadecon2_.usuario_id as usuario8_6_, formadecon2_.id as id6_, formadecon2_.id as id3_1_, formadecon2_.contato as contato3_1_, formadecon2_.criado as criado3_1_, formadecon2_.modificado as modificado3_1_, formadecon2_.observacao as observacao3_1_, formadecon2_.principal as principal3_1_, formadecon2_.tipo_formadecontato as tipo7_3_1_, formadecon2_.usuario_id as usuario8_3_1_, disponibil3_.id as id2_2_, disponibil3_.criado as criado2_2_, disponibil3_.data_fim as data3_2_2_, disponibil3_.data_inicio as data4_2_2_, disponibil3_.departamento_id as departam5_2_2_, disponibil3_.modificado as modificado2_2_, disponibil3_.teste as teste2_2_, disponibil3_.usuario_id as usuario8_2_2_ from stenovoice.usuario usuario0_ left outer join stenovoice.endereco enderecos1_ on usuario0_.id=enderecos1_.usuario_id left outer join stenovoice.formadecontato formadecon2_ on usuario0_.id=formadecon2_.usuario_id left outer join stenovoice.disponibilidade disponibil3_ on usuario0_.id=disponibil3_.usuario_id where usuario0_.id=?
org.hibernate.LazyInitializationException: illegal access to loading collection
	at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:363)
	at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
	at org.hibernate.collection.PersistentSet.hashCode(PersistentSet.java:434)
	at br.com.stenovoice.entidade.Usuario.hashCode(Usuario.java:333)
	at br.com.stenovoice.entidade.Endereco.hashCode(Endereco.java:199)
	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:352)
	at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:260)
	at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:245)
	at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:218)
	at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:900)
	at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:888)
	at org.hibernate.loader.Loader.doQuery(Loader.java:752)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
	at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
	at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
	at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:65)
	at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3072)
	at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:434)
	at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:415)
	at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:165)
	at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
	at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
	at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
	at org.hibernate.impl.SessionImpl.get(SessionImpl.java:842)
	at org.hibernate.impl.SessionImpl.get(SessionImpl.java:835)
	at br.com.stenovoice.dao.HibernateCRUDUtils.getById(HibernateCRUDUtils.java:99)
	at br.com.stenovoice.dao.BaseDAO.getByPrimaryKey(BaseDAO.java:37)
	at br.com.stenovoice.teste.EnderecoTeste.main(EnderecoTeste.java:12)
Exception in thread "main" br.com.stenovoice.exception.DAOException: org.hibernate.LazyInitializationException: illegal access to loading collection
	at br.com.stenovoice.dao.HibernateCRUDUtils.getById(HibernateCRUDUtils.java:105)
	at br.com.stenovoice.dao.BaseDAO.getByPrimaryKey(BaseDAO.java:37)
	at br.com.stenovoice.teste.EnderecoTeste.main(EnderecoTeste.java:12)
Caused by: org.hibernate.LazyInitializationException: illegal access to loading collection
	at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:363)
	at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
	at org.hibernate.collection.PersistentSet.hashCode(PersistentSet.java:434)
	at br.com.stenovoice.entidade.Usuario.hashCode(Usuario.java:333)
	at br.com.stenovoice.entidade.Endereco.hashCode(Endereco.java:199)
	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:352)
	at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:260)
	at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:245)
	at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:218)
	at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:900)
	at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:888)
	at org.hibernate.loader.Loader.doQuery(Loader.java:752)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
	at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
	at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
	at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:65)
	at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3072)
	at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:434)
	at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:415)
	at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:165)
	at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
	at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
	at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
	at org.hibernate.impl.SessionImpl.get(SessionImpl.java:842)
	at org.hibernate.impl.SessionImpl.get(SessionImpl.java:835)
	at br.com.stenovoice.dao.HibernateCRUDUtils.getById(HibernateCRUDUtils.java:99)
	... 2 more
Lavieri

ta mas tente fazer aquilo que falei ali em cima… antes de vc postar esse ultimo erro…

leia o post acima

R

Lavieri,
Estou rodando estes testes em classes de testes, como faço para ver esse erro que vc comentou?

R

Lavieri,
Tirei do mapeamento os atributos fetch e cascade, e fiz o teste. Não acusou nenhum erro.
Será que por se tratar de mais de um relacionamento esta consulta é bloqueada de alguma forma?

ffranceschi

Como já foi falado de mudar para Set, mas só para melhor entendimento

http://jroller.com/eyallupu/entry/hibernate_exception_simultaneously_fetch_multiple

R

Ok,
Cheguei a uma solução, só não sei se foi a melhor mas…
Ao invés de colocar Collection utilizei o Set e tirei do mapeamento o atributo FetchType.EAGER, deixando apenas o cascade.
Está solução me tirou o privilégio de ao chamar o usuario, trazer os demais objetos. Fazendo com que ao chamar o usuario venha apenas o usuario, e ao chamar endereço ou forma de contato o usuario carrega junto!
Valeu rapaziada, se alguem tiver uma solução melhor, por favor me avise!

Criado 25 de fevereiro de 2009
Ultima resposta 25 de fev. de 2009
Respostas 15
Participantes 4