Update e delete com hibernate

8 respostas
D

eu tenho o seguinte mapeamento para minha tabela de Unidade..

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

<hibernate-mapping package="com.vikin.conectaescola.bean">

    <class name="Unidade" table="unidade" >
        <id name="id" column="id" type="java.lang.Long">
            <generator class="sequence">
            	<param name="sequence">seq_unidade</param>
            </generator>
        </id>
 
        <property name="matriz" column="matriz" type="java.lang.Integer"  not-null="true"/>
        <property name="nome" column="nome" type="java.lang.String"  not-null="true" >
 
        <many-to-one name="coordenador" column="coordenador_id" class="Funcionario"  />
 
        <many-to-one name="instituicao" column="instituicao_id" class="Instituicao"  not-null="true"/>
    </class>
    
</hibernate-mapping>

o problema é o sequinte:

1.quando tento alterar por exemplo apenas o campo nome o hibernate monta uma query com todos os campos, ou seja, eu to passando apenas o nome da unidade no atributo nome! ai o update não funciona...

public void update(Object obj) throws HibernateException{
		Transaction tx = null;
		Session session = null;
		try{
			session = SessionFactory.currentSession();
			tx = session.beginTransaction();
			session.update(obj);
			tx.commit();		
		}catch (HibernateException e){
			tx.rollback();
		}finally{
			SessionFactory.closeSession();
		}		
	}

2. o mesmo problema acontece quando quero deletar um registro. para realizar essa operação eu tenho que primeiro setar todos os atributos para que o delete seja realizado.

public void delete(Object obj) throws HibernateException {
		Session session = null;
		Transaction tx = null;
		try{
			session = SessionFactory.currentSession();
			tx = session.beginTransaction();	
			session.delete(obj);	
			tx.commit();		
		}catch (HibernateException e){
			tx.rollback();
		}finally{
			SessionFactory.closeSession();
		}
	}

qual a melhor maneira para realizar essa duas operações??

8 Respostas

_fs

Para deletar basta que a propriedade mapeada para a PK do objeto tenha valor.

E o update do Hibernate sempre envia todos os campos. Seria impossível para ele saber que apenas a propriedade X ganhou valor, sendo que seria perfeitamente possível que as outras propriedades tivessem ganho o valor null.
O que você pode fazer para contornar este problema é:

Unidade u = ( Unidade ) session.get( Unidade.class, id );
u.setNome( nomePassadoComoParametro );

Ou sempre trabalhe com o objeto inteiramente populado, assim quando fizer session.update( obj ), nenhum dado será perdido.

D

blz! no caso de update vou usar esse codigo q vc me passou mais ainda tem um problema com ele é q tipo. Ele executa 2 query ou seja ele tb ta trazendo as informações de Insitução…
O correto não seria apenas trazer as informações da Unidade??

Outra coisa é que no caso do delete os campos Nome, matriz, Instituição estão como not null ai não adianta apenas informar o Id. quando tiro o not null no mapeamento funciona…

_fs

Se você declara um relacionamento may-to-one entre objetos o Hibernate traz todos eles. A database que está usando suporta JOINs?

E quanto ao delete, não enfrentei este problema, porém você pode fazer o load antes do delete.

D

oi, Lipe!
Antes de tudo quero te agradecer pela ajuda! Obrigado! hehheheeh…

eu to usando postgresql!

Qual a outra maneira para ele não trazer tudo? devo usar o que no lugar do relacionamento “may-to-one”?

_fs

Relaxa :smiley:

O Hibernate sempre vai trazer, pois não é possível declarar relacionamentos many-to-one como Lazy. O que você pode fazer, mas não tenho certeza se adianta, é declarar o atributo lazy nas classes.

Se for utilizar o outer_join, vá na documentação do Hibernate ($hibernate_home$\doc\reference\en\html_single\index.htm), no capítulo
3.5.2. Outer Join Fetching

Se estiver usando o Hibernate3, leia aqui também
http://www.hibernate.org/250.html#A11

gilliard_santos

oi duosan, eu estava mexendo até esses dias numa aplicação pra testar o hibernate 3 e tive um problema contrario do teu…
eu tinha um relacionamento <many-to-one> e ele nao trazia os objetos do objeto que eu tava buscando.
o meu exemplo (bem tosco) eu fiz uma classe Fornecedor que tinha um objeto da classe Cidade e um da classe Telefone…
pra ele carregar os objetos Cidade e Telefone quando eu buscava o Fornecedor eu tive que colocar isso no select do meu FornecedorDAO

Criteria sqlCriteria = hibSession.createCriteria(Fornecedor.class);
sqlCriteria.setFetchMode("Cidade", FetchMode.JOIN); 
sqlCriteria.setFetchMode("Telefone", FetchMode.JOIN);
// "Cidade" e "Telefone" é o 'name' que está no &lt;many-to-one&gt; do Fornecedor.hbm.xml, como no exemplo a seguir.

ou entao no meu hbm.xml da classe fornecedor eu coloquei isso

&lt;many-to-one
	    name="Telefone"
	    class="empresa.Telefone"
	    fetch="join"
    &gt;

você pode setar o seu FetchMode tanto no hbm.xml quanto no proprio método, isso vai depender de como você vai querer usar.
por default o na minha aplicação (hibernate 3) nao trouxe todos os objetos… ma se pra você foi o contrario, tenta colocar outro tipo de FetchMode… eu nao sei qual usar, mas talvez assim pode dar certo

D

valeu “gilliard_santos”! Quando chegar em casa eu vou testar essa sua dica… pra adiantar já vou da uma procurado sobre o assunto na documentação do hibernate…

Só pra tirar uma dúvida… qual o banco que você ta usando??
É que eu pensei que ele trazia os dados do objeto se meu banco tivesse suporte a “join” e por default o hibernate trata join automatico quando o banco tem suporte.

Um grande abraço…

gilliard_santos

eu fiz com o HSQL…

Criado 14 de março de 2005
Ultima resposta 31 de mar. de 2005
Respostas 8
Participantes 3