Duvida Hibernate

8 respostas
vinicius_roc

Bom pessoal eu testou com o seguinte problema. Tudo funciona como deve mas esta lento e acredito que haja alguma forma de otimizar isso.

Oque acontece é o seguinte:

Tenho um metodo em Hibernate readAll que retorna todos os usuarios do Banco de Dados

E ele possui uma cheve estrangeira de Area.

Então quando pego estes Usuarios, a area vem com o numero do id dela. Ai preciso fazer um loop que seta o Campo Areaname do meu model. E isso leva um tempo.

UsuarioDAO udao = new UsuarioDAO();
ArrayList<Usuarios> user = udao.readAll();

for(Usuarios u : user){
       u.setAreaname;
}

O que eu quero saber é se tem como atraves de Annotations ou alguma outra coisa, fazer com que o hibernate ja preencha essa variavel?

Segue as entidades:

Usuarios:

Id PK
Nome
Area FK area.ID
Ramal FK ramal.ID
Baia FK baia.ID

Area:

Id PK
Nome
area_mestra FK area.id

Muito obrigado

Att,

Vinicius Roberto

8 Respostas

filipenf

Tem sim, é só você fazer o mapeamento usando ManyToOne. Tipo:

@JoinColumn(name = "AREA", referencedColumnName = "AREA")
	@ManyToOne
public Area getArea()...

Logicamente a classe Area também deverá estar mapeada.

vinicius_roc

Ok, então o join fica acima do metodo get certo?

@JoinColumn(name = "AREA", referencedColumnName = "AREA") @ManyToOne public String getAreaname()...

Só para não deixar duvida name é o nome da tabela e referecedColumnName é o nome do campo? no caso area e nome respectivamente?

E o model da Area ainda nao esta mapeado porque estou aprendendo agora, então estou testando no usuarios. O mapeamento é o simples mesmo ou tem alguma coisa a mais?

Obrigado

Att,

Vinicius Roberto

vinicius_roc

Por favor

Alguem sabe me dizer se entendi certo e se é só o mapeamento basico mesmo?

Obrigado

Att,

Vinicius Roberto

J

Acho que, pra sua dúvida ficar melhor esclarecida, posta como está o POJO inteiro, tanto de um como de outro. Assim, será fácil ver o seu relacionamento.

vinicius_roc

Classes:

import MZSuporte.dao.AreaDAO;
import java.io.Serializable;
import javax.persistence.*;


@Entity
public class Usuarios implements Serializable {

    @Id
    @GeneratedValue
    private String id;
    @Column(name = "nome", nullable = false, length = 40)
    private String nome;
    @Column(name = "area", nullable = false, length = 2)
    private String area;
    @Column(name = "ramal", nullable = true, length = 4)
    private String ramal;
    @Column(name = "baia", nullable = true, length = 4)
    private String baia;
    @Transient
    private String areaname;
    //mais getters & setters
package MZSuporte.model;

public class Area implements java.io.Serializable {
    
    private String id;
    private String nome;
    private int area;
    //mais getters & setters

Projeto fisico das duas tabelas

Area

ID int(2) Not null PK
Nome varchar(20) Not null
Area int(2) FK (Area.ID)

Usuarios

ID int(5) Not null PK
Nome varchar(40) Not null
Area Number Not null FK (Area.ID)
Ramal Number FK (Ramais.Numero)
Baia Number FK (Baia.ID)

Vlw

Abss

Att,

Vinicius Roberto

F

Olá!

De acordo com o seu modelo, sugiro que você implemente essas duas classes da seguinte forma:

Usuario.java:

import java.io.Serializable;
import javax.persistence.*;  

@Table(name = "Usuarios")
@Entity
public class Usuario implements Serializable {  
   
     @Id  
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;

     @Column(name = "nome", nullable = false, length = 40)  
     private String nome;  

     @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
     @PrimaryKeyJoinColumn
     @JoinColumn(nullable = false)
     private Area area;

     @Column(name = "ramal", nullable = true, length = 4)  
     private String ramal;

     @Column(name = "baia", nullable = true, length = 4)
     private String baia;

     @Transient
     private String areaName;

     public void setArea(Area area){
         this.area=area;
         if (area != null){
              setAreaName(area.getNome());
         } else {
              setAreaName(null);
         }
     }

     private void setAreaName(String areaName){
         this.areaName = areaName;
     }


     public String getAreaName(){
         return this.areaName;
     }

     //mais getters & setters

Area.java:

import java.io.Serializable;
import javax.persistence.*;

@Table(name = "Areas")
@Entity
public class Area implements Serializable {  
       
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;  

     @Column(nullable = false, unique = true)
     private String nome;

     @Column(nullable = false, unique = true)
     private Integer area;  

     //mais getters & setters

Não compilei esse código, então, não garanto que não tenha nenhum erro de compilação.
Mas a idéia é definir os mapeamentos no Annotations.
E a política do cascade está exemplificada, e você pode optar por outra.

E para mais informações sobre os mapeamentos olha a documentação do Hibernate Annotations:
http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/

Att.

vinicius_roc

Vlw Fabricio,

Quase funcionou.

Ele esta gerando esse codigo SQL:

select
        this_.id as id0_1_,
        this_.area_id as area5_0_1_,
        this_.baia as baia0_1_,
        this_.nome as nome0_1_,
        this_.ramal as ramal0_1_,
        area2_.id as id1_0_,
        area2_.area as area1_0_,
        area2_.nome as nome1_0_ 
    from
        Usuarios this_
    inner join
        Area area2_
            on this_.area_id = area2_.id
    order by
        this_.nome asc

E ae da erro no "this_.area_id" diz que não existe esse campo, então eu testei direto no BD e deu o mesmo erro então tirei o "id" e dexei só assim "this_.area" e funcionou. O que esta fazendo com que ele adicione este _id no final??

Obrigado

Att,

Vinicius Roberto

vinicius_roc

Descobri ja!

Só precisei adicionar o name=“area” no @joincolumn e resolveu.

E tambem consegui retirar o areaname pegando o nome direto no property coloquei user.area.nome

Mas agora estou com uma serie duvida.

Não estou conseguindo referienciar direto em um formulario o id da area.

coloco <html:select property=“user.area.id”>

e não da certo ele retorna erro.

Então como devo referenciar um Atributo que esta dentro de um Objeto dentro de outro Objeto?

Outra duvida:

Devo colocar os gets e sets da classe area na classe usuario? não neh?

Muito Obrigado

Att,

Vinicius Roberto

Criado 19 de junho de 2009
Ultima resposta 25 de jun. de 2009
Respostas 8
Participantes 4