[RESOLVIDO] Hibernate, duvida no carregamento

Olá pessoal,

estou iniciando com o Hibernate, estou usando o 3, e tenho uma duvida quanto ao carregamento que o Hibernate faz de uma entidade qualquer.

Bom, a duvida é o seguinte. Tem como eu implementar algum método para ele seja chamado sempre que uma entidade for carregada através do Entity Manager?

Vamos supor, quero que, sempre que um objeto for recuperado do banco de dados, um atributo, seila, flagCarregado, seja setado para true.

Nessa caso, poderia ser, tanto implementando um método, quando colocando em um desses arquivos xml dele… porque o objetivo é apenas colocar um valor fixo em um atributo, quando um objeto for recuperado. Seria bom poder editar isso uma vez só para todos os objetos recuperados pelo EM. Se não der, pode ser de 1 em 1 mesmo.

Tem como fazer isso?

VLW

Baison, tem sim. O Hibernate te dá a possibilidade de criar interceptors e associa-los ou com uma session especifica ou com toda a “aplicacao”. Assim, vc pode por exemplo implementar a interface Interceptor para que ela faça esse trabalho que vc descreveu.

No entanto, acho que essa não seria a melhor solução para o seu caso. Que tal você colocar o carregamento dessa sua entidade num DAO e sempre que vc chamar o método no seu DAO que faz o carregamento dessa entitidade ele faz essa atribuição que vc precisa?!?!

[quote=pafuncio][quote=baison]

Tem como fazer isso?

[/quote]

Baison, tem sim. O Hibernate te dá a possibilidade de criar interceptors e associa-los ou com uma session especifica ou com toda a “aplicacao”. Assim, vc pode por exemplo implementar a interface Interceptor para que ela faça esse trabalho que vc descreveu.

No entanto, acho que essa não seria a melhor solução para o seu caso. Que tal você colocar o carregamento dessa sua entidade num DAO e sempre que vc chamar o método no seu DAO que faz o carregamento dessa entitidade ele faz essa atribuição que vc precisa?!?![/quote]

É, eu tinha pensado em fazer assim mesmo, so que, como o Hibernate tem tantos recursos e faz algumas “mágicas”, imaginei que ele poderia fazer isso por mim.

Vou colocar o meu caso aki:
Eu tenho em todas as minhas entidades um atributo chamado estadoInterno. Esse atributo é um enum do tipo EstadoObjeto que tem os estados:
NOVO, ANTIGO_INALTERADO, ANTIGO_ALTERADO, ANTIGO_EXLUIDO.

Sempre que um entidade é recuperada, o estado dela é ANTIGO_INALTERADO, e quando ela é instancia, ou seja, foi instanciada mais ainda não foi gravada no banco, o seu estado é NOVO.

O estado novo ja esta ok, porque, sempre que um classe instanciada, no construtor de cada uma, o atributo é inicializado com NOVO.

Bom, eu implementei um GenericDAO que ja faz todo o trabalho usando o JPA. Esse GenericDAO é parametrizável, pedindo um tipo T qualquer. Então, as classes filhas dele, so o estendem para colocar o tipo correto.

Então, se alguma classe filha quiser fazer um método para recuperar o objeto do bd de alguma outra forma diferente, além das ja implementadas, ela vai ter que sempre setar o estado para ANTIGO_ALTERADO. Esse comportamento, eu gostaria que ja ficasse automático.

Vc falou desse interceptors, o que é isso resumidamente? é muito complicado?

VLW

Bom, olhando um artigo no javaworld achei exatamente o que eu queria.

Para implementar esse tipo de carregamento, utiliza-se o conceito de callbacks.

Aki está o trecho do artigo que descreve isso:

JPA provides callback methods for performing actions at different stages of persistence operations. Imagine that you want to update a customer record, but, before you update, you want to remove the hyphen from the zip code if one is present. Or say that you want to populate some transient fields after a successful fetch. JPA provides listeners for these kinds of activities before and after each fetch, insert, or update operation. The callback methods can be annotated as any of the following:

* @PostLoad
* @PrePersist
* @PostPersist
* @PreUpdate
* @PostUpdate
* @PreRemove
* @PostRemove

You can write the callback methods in the entity class itself, or you can write them in a separate class and reference them in the entity class with @EntityListeners, as shown in Listing 9.
Listing 9. implementing callback

@EntityListeners({CustListner.class})
@Entity(name = "CUSTOMER") //Name of the entity
public class Customer implements Serializable{
...
...
}
public class CustListner {
    @PreUpdate
    public void preUpdate(Customer cust) {
         System.out.println("In pre update");
    }
    @PostUpdate
    public void postUpdate(Customer cust) {
         System.out.println("In post update");
    }
}

Link: http://www.javaworld.com/javaworld/jw-01-2008/jw-01-jpa1.html?page=4

Espero que ajude a quem estava com essa duvida também.