Opa
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)
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 )