Duvida de relacionamento hibernate..como trazer os filhos sempre?

Opa :smiley:

Tenho um relacionamento 1-N e criei da seguinte maneira:

EmpresaBean

@OneToMany(mappedBy="empresa", fetch=FetchType.EAGER)
	@Cascade(CascadeType.ALL)
	private Collection<CargaBean> cargas = new ArrayList<CargaBean>();

CargaBean

@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name="id_empresa", insertable=true, updatable=true)
	@Fetch(FetchMode.JOIN)
	private EmpresaBean empresa;

Eu qria que a lista de cargas vc atualizada sempre que eu desse um empresaBean.getCargas()

Tem como fazer isso por annotations ou preciso chamar um método de consulta no BD?

[]'s

Sim,
mapeie como lazy = false

onde que faço isso?

eu mudei o Fetch pra LAZY e não resolveu!

EmpresaBean

@OneToMany(mappedBy="empresa", fetch=FetchType.EAGER)
	@Cascade(CascadeType.ALL)
	@LazyCollection(LazyCollectionOption.FALSE)
	private Collection<CargaBean> cargas = new ArrayList<CargaBean>();

Carga

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name="id_empresa", insertable=true, updatable=true)
	@Fetch(FetchMode.JOIN)
	@LazyToOne(LazyToOneOption.FALSE)
	private EmpresaBean empresa;

O que estou fazendo de errado?

[]'s

[quote=mendigosujo]onde que faço isso?

eu mudei o Fetch pra LAZY e não resolveu!

EmpresaBean

@OneToMany(mappedBy="empresa", fetch=FetchType.EAGER)
	@Cascade(CascadeType.ALL)
	@LazyCollection(LazyCollectionOption.FALSE)
	private Collection<CargaBean> cargas = new ArrayList<CargaBean>();

Carga

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name="id_empresa", insertable=true, updatable=true)
	@Fetch(FetchMode.JOIN)
	@LazyToOne(LazyToOneOption.FALSE)
	private EmpresaBean empresa;

O que estou fazendo de errado?

[]'s[/quote]

Se vc mudar o fech pra lazy vc ta dizendo q ele tem q ser preguiçoso, entao vai continuar o problema, ali é EAGER msm, guloso, no property vc mapeia Lazy=“false”.
Ex:

<property name="nome" column="nome" type="string" unique="false" optimistic-lock="true" lazy="false" />

EDIT: Isso no xml.
Vc ta usando o Generate do Hibernate ou mapeando nos hbms da vida?

como assim? Não uso hbm nenhum
eu faço só a annotation nas classes :oops:

@Entity
@Table(name="empresa", schema="public")
@SequenceGenerator(sequenceName="empresa_id_empresa_seq", name="empresa_id_empresa_seq")
public class EmpresaBean implements Empresa, Serializable{

Como que fica esse property?

[quote=mendigosujo]como assim? Não uso hbm nenhum
eu faço só a annotation nas classes :oops:

@Entity
@Table(name="empresa", schema="public")
@SequenceGenerator(sequenceName="empresa_id_empresa_seq", name="empresa_id_empresa_seq")
public class EmpresaBean implements Empresa, Serializable{

Como que fica esse property?[/quote]

XMl se vc tivesse usando o Hibernate de outra forma…
Coloque essa anotação: @Proxy(lazy=false) :smiley:

Se eu fizer:

@Entity
@Table(name="empresa", schema="public")
@SequenceGenerator(sequenceName="empresa_id_empresa_seq", name="empresa_id_empresa_seq")
@Proxy(lazy=false)
public class EmpresaBean implements Empresa, Serializable{

Ele não me busca nada nem na primeira vez que eu entro hehe

Eu preciso por o @Proxy na classe ‘pai’ ou na filha?

[quote=mendigosujo]Se eu fizer:

@Entity
@Table(name="empresa", schema="public")
@SequenceGenerator(sequenceName="empresa_id_empresa_seq", name="empresa_id_empresa_seq")
public class EmpresaBean implements Empresa, Serializable{
@Proxy(lazy=false)

Ele não me busca nada nem na primeira vez que eu entro hehe

Eu preciso por o @Proxy na classe ‘pai’ ou na filha?[/quote]

É em cima do public class

@Entity
@Table(name="empresa", schema="public")
@SequenceGenerator(sequenceName="empresa_id_empresa_seq", name="empresa_id_empresa_seq")
@Proxy(lazy=false)
public class EmpresaBean implements Empresa, Serializable{

Sim…eu coloquei em cima…é que na hora do edit, eu coloquei na mão e não tinha percebido haha

você precisa chamar session.refresh() no seu objeto para poder atualizar a lista dele, já que a coleção só é carregada uma vez enquanto a entidade for gerenciada (managed).

como que eu faço isso?..alias, onde eu coloco o session refresh? pq eu criei um dão ‘generico’ para operacoes padrão.

po, ele só atualiza a lista qdo eu altero haha…ai eu retorno pra pagina e ta certo, mas qdo eu excluo ou incluo um novo registro, ele nao atualiza a lista!

eu tentei um session.refresh(object) antes do commit(), mas ele não serve e eu recebo a exception que não existe um objeto daquele no banco…mas eu recebo isso pq eu não mando o objeto ‘pai’ ( Empresa ) para o BD…eu mando o filho pq se eu mandar o pai, eu fico recebendo exceção de que estou com outra conexão aberta e eu não sabia mais o q fazer…podem notar q está comentado os session.close() pq ai ele dava pau e não abria outro…ai eu deixei assim e até agora não tive problemas…vou colcoar meu sessionFactory e meu config.xml tb

session factory

public class HibernateSessionFactory {

	/**
	 * Construtor padrão.
	 */
	private HibernateSessionFactory() {
	}

	/**
	 * Localização do arquivo de configuração hibernate.cfg.xml 
	 */
	private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";

	/** 
	 * Instância única de configuração do hibernate 
	 */
	private static final Configuration cfg = new AnnotationConfiguration();

	/** 
	 * Instância única do hibernate SessionFactory 
	 */
	private static org.hibernate.SessionFactory sessionFactory;

	/**
	 * Inicializa a configuração caso ainda não tenha sido feita e retorna 
	 * a atual instância
	 * 
	 * @return Atual instância do SessionFactory
	 */
	public static SessionFactory getInstance() {
		if (sessionFactory == null)
			hibernateSessionFactory();
		return sessionFactory;
	}

	/**
	 * Retorna a instância atual de Session e caso precise,
	 * ela é inicializada
	 * 
	 * @return Session 
	 * @throws HibernateException
	 */
	public Session openSession() {
		return sessionFactory.getCurrentSession();
	}

	/**
	 * Obtém a session atual através do sessionFactory
	 * 
	 * @return Session
	 */
	public Session getCurrentSession() {
		return sessionFactory.getCurrentSession();
	}

	/**
	 * Inicializa a session factory de uma maneira segura.
	 */
	private static synchronized void hibernateSessionFactory() {

		Logger log = Logger.getLogger(HibernateSessionFactory.class);
		if (sessionFactory == null) {
 

			try {
				cfg.configure(CONFIG_FILE_LOCATION);
				String sessionFactoryJndiName = cfg.getProperty(Environment.SESSION_FACTORY_NAME);
				if (sessionFactoryJndiName != null) {
					cfg.buildSessionFactory();
					log.debug("get a jndi session factory");
					sessionFactory = (SessionFactory) (new InitialContext()).lookup(sessionFactoryJndiName);
				} else{
					log.debug("classic factory");
					sessionFactory = cfg.buildSessionFactory();
				}

			} catch (Exception e) {
				System.err.println("%%%% Error Creating HibernateSessionFactory %%%%");
				e.printStackTrace();
				throw new HibernateException("Could not initialize the Hibernate configuration");
			}
		}
	}
 
	/**
	 * Fecha a sessionFactory
	 */
	public static void close(){
		if (sessionFactory != null)
			sessionFactory.close();
		sessionFactory = null;
 
	}
}
public class GenericDAO<T> {

	/**
	 * Objeto de log da classe
	 */
	protected static final Logger logger = Logger.getLogger(br.com.ms.hibernate.dao.GeralDAO.class);
	
	/**
	 * Objeto da sessão
	 */
	protected Session session;

	/**
	 * Transaction referente
	 */
	protected Transaction transaction;

	/**
	 * Classe em questão
	 */
	@SuppressWarnings("unchecked")
	protected Class classe;

	/**
	 * Construtor padrão que recebe uma classe para ser persistida
	 * 
	 * @param classe
	 */
	public GeralDAO(Class<T> classe) {
		this.classe = classe;
		logger.info("Setando sessão atual");
		session = HibernateSessionFactory.getInstance().openSession();
		logger.info("Setando transaction atual");
		
	}

	/**
	 * Salva o objeto enviado no banco de dados
	 * 
	 * @param object
	 */
	public void save(Object object) {
		try 
		{
			logger.info("Preparando para salvar objeto: [ " + classe.getSimpleName() + " ]");
			transaction = session.beginTransaction();
			session.save(object);
			transaction.commit();
			logger.info("Objeto [ " + classe.getSimpleName() + " ] salvo com sucesso");
		} catch (Exception ex) {
			logger.error("Erro ao salvar objeto: [ " + classe.getSimpleName() + " ]", ex);
			rollback();
		} finally {
			try {
				if(session.isOpen()){
					logger.error("Finalizando sessao");
					//session.close();
				}
			} catch (HibernateException hex) {
				logger.error("Erro ao finalizar sessao", hex);
			}
		}
	}

	/**
	 * Atualiza os dados do objeto enviado no banco de dados
	 * 
	 * @param object
	 */
	public void update(Object object) {
		try 
		{
			transaction = session.beginTransaction();
			logger.info("Preparando para atualizar objeto: [ " + classe.getSimpleName() + " ]");
			session.update(object);
			transaction.commit();
			logger.info("Objeto [ " + classe.getSimpleName() + " ] atualizado com sucesso");
		} catch (Exception ex) {
			logger.error("Erro ao atualizar objeto: [ " + classe.getSimpleName() + " ]", ex);
			rollback();
		} finally {
			try {
				if(session.isOpen()){
					logger.error("Finalizando sessao");
					//session.close();
				}
			} catch (HibernateException hex) {
				logger.error("Erro ao finalizar sessao", hex);
			}
		}
	}

	/**
	 * Exclui os dados do objeto no banco de dados
	 * 
	 * @param object
	 */
	public void delete(Object object) {
		try 
		{
			transaction = session.beginTransaction();
			logger.info("Preparando para deletar objeto: [ " + classe.getSimpleName() + " ]");
			session.delete(object);
			transaction.commit();
			logger.info("Objeto [ " + classe.getSimpleName() + " ] deletado com sucesso");
		} catch (Exception ex) {
			logger.error("Erro ao deletar objeto: [ " + classe.getSimpleName() + " ]", ex);
			rollback();
		} finally {
			try {
				if(session.isOpen()){
					logger.error("Finalizando sessao");
					//session.close();
				}
			} catch (HibernateException hex) {
				logger.error("Erro ao finalizar sessao", hex);
			}
		}
	}

	/**
	 * Busca um determinado registro através de um identificador
	 * 
	 * @param id
	 * @return Object
	 */
	public Object findByID(Integer id) {
		Object object = null;
		try {
			transaction = session.beginTransaction();
			logger.info("Preparando para buscar objeto: [ " + classe.getSimpleName() + " ] de ID = [ " + id + " ]");
			object = session.get(classe, id);
			transaction.commit();
			logger.info("Objeto [ " + classe.getSimpleName() + " ] encontrado com sucesso");
		} catch (Exception ex) {
			logger.error("Erro ao erro ao buscar: [ " + classe.getSimpleName() + " ]", ex);
			rollback();
		} finally {
			try {
				if(session.isOpen()){
					logger.error("Finalizando sessao");
					//session.close();
				}
			} catch (HibernateException hex) {
				logger.error("Erro ao finalizar sessao", hex);
			}
		}
		logger.info("Objeto [ " + classe.getSimpleName() + " ] sendo retornado");
		return object;
	}

	/**
	 * Busca todos resultados de um objeto
	 * 
	 * @return List resultados do objeto
	 */
	public List<T> findAll(){
		List<T> results = new ArrayList<T>();
		try{
			transaction = session.beginTransaction();
			logger.info("Preparando para buscar todos objetos: [ " + classe.getSimpleName() + " ]");
			Query query = session.createQuery("from " + classe);
			logger.info("Objetos [ " + classe.getSimpleName() + " ] encontrado com sucesso");
			results = query.list();
			transaction.commit();
		} catch(Exception ex){
			logger.error("Erro ao erro ao buscar: [ " + classe.getSimpleName() + " ]", ex);
			rollback();
		} finally {
			try {
				if(session.isOpen()){
					logger.error("Finalizando sessao");
					//session.close();
				}
			} catch (HibernateException hex) {
				logger.error("Erro ao finalizar sessao", hex);
			}
		}
		logger.info("Lista de objetos [ " + classe.getSimpleName() + " ] sendo retornado");
		return results;
	}
	
	/**
	 * Finaliza a sessão atual deste objeto
	 */
	public void closeSession() {
		/*if (session != null && session.isOpen()) {
			session.close();
			session = null;
		}*/
	}
	
	/**
	 * Efetua o rollback do transaction
	 */
	protected void rollback(){
		if (transaction != null) {
			try {
				logger.error("Efetuando rollback de transacao");
				transaction.rollback();
			} catch (HibernateException hex) {
				logger.error("Erro ao efetuar rollback", hex);
			}
		}

e meu 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>

        <!-- Database connection settings -->
        <property name="connection.driver_class">org.postgresql.Driver</property>
        <property name="connection.url">jdbc:postgresql://localhost:5432/testeJSF</property>
        <property name="connection.username">postgres</property>
        <property name="connection.password">postgres</property>

		<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

		<mapping class="br.com.ms.bean.carga.CargaBean"/>
		<mapping class="br.com.ms.bean.empresa.EmpresaBean"/>
		<mapping class="br.com.ms.bean.login.LoginBean"/>
    </session-factory>

</hibernate-configuration>

sempre que você atualiza algo no banco, precisa atualizar ou recarregar a lista para manter o estado dos objetos em memória sincronizado com o que está no banco

então Fabio…não consigo fazer isso pq não to passando o objeto Pai…se eu passar ele, eu fico com uma porrada de erro aqui :oops: … erro que a session ta fechada ou que tento usar o mesmo objeto em 2 sessions…eu fiquei doido e desiti…ai eu atualizo e removo o objeto da seguinte maneira:

CargaDAO dao = new CargaDAO(br.com.portaldascargas.bean.carga.CargaBean.class);
		dao.delete(getCargaBean());

Todos meus DAO extendem o GeralDAO e não tem nenhum método dentro, somente o construtor!

Eu mudei os métodos para

Session session = HibernateFactory.getInstance().getSession();
		Transaction tx = session.beginTransaction();
		session.delete(obj);
		EmpresaBean empresa = (EmpresaBean)object;
		tx.commit();
		session.refresh(empresa.getCargas());
		session.close();

e recebo a exceção

isso ta acontecendo depois dos commits pq ele tenta atualizar um objeto que não existe mais ( no caso do delete )