Hibernate e DDL

13 respostas
J

Galera,

É possível utilizando annotations em minha classe gerar no arquivo DDL as minhas check constraints? alguém sabe como fazer isso?

class Pessoa {

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

    // gostaria de utilizar aqui uma check constraint para que a coluna do banco de dados aceite somente 1 para Física e 2 para Juridica.
    @Column(name = "tpo_pessoa", nullable=false) 
    private int tipoPessoa

......
}

Jukinha :?:

13 Respostas

emmanuel.silva

Você pode fazer isso usando enuns fazendo com que que aquele seu atributo tenha somente os valores dentro do enum.

Entidade:

@Entity
@Table(name = "pessoa")
public class Pessoa implement Serializable {

    @Column(name = "pe_classificacao", nullable = false)
    @Enumerated(EnumType.STRING)
    private PessoaType peClassificacao;

    //gets and setters

Enum:

public enum PessoaType {
    /** Sinaliza que a pessoa é Física */
    FISICA("Física"),
    /** Sinaliza que a pessoa é Jurídica */
    JURIDICA("Jurídica");
    
    private String key;
    
    PessoaType(String key) {
        this.key = key;
    }
    
    public String toString() {
        return key;
    }
    
    private static final long serialVersionUID = 1L;
}
J

Emmanuel,

Acho que me expressei mal, no caso do ambiente java, a sua solução é plausível, porém, para gerar uma regra que aceite somente os valores ‘Física’ e/ou 'Jurídica" no banco de dados é que não sei se é possível o mapeamento. Você sabe como eu faço o mapeamento na classe utilizando annotations para gerar uma check constraint para que minha DDL fique com o seguinte código:

ALTER TABLE pessoa ADD CONSTRAINT ck_pss_pe_classificacao
    CHECK (pe_classificacao IN ('Física', 'Jurídica'));

@Entity
 @Table(name = "pessoa")
 public class Pessoa implement Serializable {
 
     @Column(name = "pe_classificacao", nullable = false)
     @Enumerated(EnumType.STRING)
     private PessoaType peClassificacao;
 
     //gets and setters

Agradeço antecipadamente por sua colaboração…

Jukinha :!:

emmanuel.silva

Não eu sei como fazer isso, mais se for o caso vc pode usar um campo ‘Enum’ no banco de dados, ai o registro só será salvo se o campo for equivalente aos campos dos enums…

J

Como eu faria para criar o campo Enum no banco de dados, você teria algum exemplo.

emmanuel.silva

Ficara assim, o campo pe_tipo, só pode conter os valores, ‘’ (branco), FISICA e JURIDICA.

CREATE TABLE `Pessoa` (
  `pe_tipo` enum('','FISICA','JURIDICA') NOT NULL
);
J

Vou fazer um teste.

Obrigado Emmanuel.

Jukinha :wink:

fsquadro

Aproveitando o assunto…

Eu tenho a seguinte classe:

@Entity(name="Shinigami")
@Table(name="tb_brian_shinigami")        
public class Shinigami {
    
    @Id
    @GeneratedValue
    @Column(name="id_shinigami")
    private int id;
    
    @Column(name="txt_nome")
    private String nome;
   
    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER, targetEntity=Shinigami.class, mappedBy="Shinigami")
    private Set emails = new HashSet();
    
    @ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.EAGER,  targetEntity=Shinigami.class)    
    private Set eventos = new HashSet();
    
    // gets and setters 
  
}

Quais as anotações utillizar para que sejam criadas as tabelas de ligação (tb_shinigami_evento e tb_shinigami_email)
Desta forma que estou tentando não esta funcionando.

Obrigado.

plentz

fsquadro:
Quais as anotações utillizar para que sejam criadas as tabelas de ligação (tb_shinigami_evento e tb_shinigami_email)
Desta forma que estou tentando não esta funcionando.

Se você mapeou o caminho inverso (o lado ManyToOne) ele deveria ter criado normalmente.

fsquadro

plentz,

Não estou conseguindo fazer funcionar, já descobri qual é o erro, porém não sei como resolve-lo.

Eu tenho a seguinte classe:

@Entity(name="Shinigami")
@Table(name="tb_brian_shinigami")   

public class Shinigami {
    
    @Id
    @GeneratedValue
    @Column(name="id_shinigami")
    private int id;
    
    @Column(name="txt_nome")
    private String nome;
   
    /*@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER, targetEntity=Shinigami.class, mappedBy="Shinigami")
    private Set emails = new HashSet();
    */
    
    [b]@ManyToMany(targetEntity=hiberapp0.Shinigami.class, cascade={CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(
    name="tb_brian_shinigami_evento",
    joinColumns={@JoinColumn(name="id_evento", table="tb_brian_evento")}, 
    inverseJoinColumns = @JoinColumn(name="id_shinigami", table="tb_brian_shinigami")     
    ) [/b]  
    
    private Set eventos = new HashSet();

Ele cria a tabela, porem ele cria da seguinte forma:

CREATE TABLE tb_brian_shinigami_evento
(
  id_evento int4 NOT NULL,
  id_shinigami int4 NOT NULL,
  CONSTRAINT tb_brian_shinigami_evento_pkey PRIMARY KEY (id_evento, id_shinigami),
  CONSTRAINT fkfd7434b9210b4ff5 FOREIGN KEY (id_shinigami)
      REFERENCES tb_brian_shinigami (id_shinigami) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  [b]CONSTRAINT fkfd7434b99ec330ed FOREIGN KEY (id_evento)
      REFERENCES tb_brian_shinigami (id_shinigami) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION[/b]
)

E o problema está ai, o id_evento tem referenciar a tabela tb_brian_evento e não a tabela tb_brian_shinigami. Porem não sei como fazer.

Esse é um problema, o outro é que eu não sei como fazer para mapear um relacionamento 1 para muitos (Ex. Shinigami pode ter varios emails, criar um tabela no banco com id_shinigami, e um campo email)

Já agradeço a ajuda.

fsquadro

Descobri o que era o erro, eu estava fazendo o seguinte:

@ManyToMany(targetEntity=hiberapp0.Shinigami.class, cascade={CascadeType.PERSIST, CascadeType.MERGE})
     @JoinTable(
     name="tb_brian_shinigami_evento",
     joinColumns={@JoinColumn(name="id_evento", table="tb_brian_evento")}, 
     inverseJoinColumns = @JoinColumn(name="id_shinigami", table="tb_brian_shinigami")     
     )  
     
     private Set eventos = new HashSet();

Ou seja, estava dentro da classe Shinigami, e querendo envocar algo da classe envento. e passando no targetEntity a classe errada (targetEntity=hiberapp0.Shinigami.class)
O código certo, fica da seguinte forma:

@ManyToMany(targetEntity=hiberapp0.Evento.class, cascade={CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(
    name="tb_brian_shinigami_evento",
    joinColumns={@JoinColumn(name="id_evento", table="tb_brian_evento")},
    inverseJoinColumns = @JoinColumn( name="id_shinigami")
    ) 
    
    private Set eventos = new HashSet();

Agora vou continuar tentando o @OneToMany.
Se alguem poder ajudar.

Obrigado.

Fabio_Kung

@ManyToOne não precisa de tabela de relacionamento. Vai ser gerada apenas uma coluna de chave estrangeira, suficiente para mapear o relacionamento.

plentz

Acho que você poderia melhorar sua solução da seguinte forma:

@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE}) private Set<Evento> eventos = new HashSet<Evento>();

fsquadro

Fabio,

Eu descobri por que estava dando errado.

@OneToMany
@JoinTable(
      name="tb_brian_shinigami_emails",
      joinColumns={@JoinColumn(name="id_shinigami")})
private Set emails = new HashSet();

Ele estava reclamando de era um generic type. Então eu fiz da seguinte maneira

@OneToMany
@JoinTable(
      name="tb_brian_shinigami_emails",
      joinColumns={@JoinColumn(name="id_shinigami")})
private Set<String> emails = new HashSet();

Mas, agora eu tenho uma dúvida. Ele cria a tabela, e o campo texto que ele cria, é um nome estranho. Como faço para colocar o nome que eu quero. (Ex. Ele cria o campo com o nome “elt”, e eu quero que o campo se chame email.)

Obrigado.

Criado 16 de março de 2007
Ultima resposta 19 de mar. de 2007
Respostas 13
Participantes 5