Hibernate - Chave estrangeira e mapeamento

15 respostas
D

Gente,

Não entendi alguns conceitos de chave estrangeira no Hibernate. Vejam só minhas tabelas filme, gênero e categoria. Um filme deve conter um gênero e uma categoria. Eu já tinha criado as tabelas no (MySQL5) dessa forma:
(filme)
id : int 	 | auto incr | PK
nome: varchar
genero: int
categoria int

índice fk_filme1 -> campo genero aponta para “id” da tabela genero
índice fk_filme2 -> campo categoria aponta para “id” da tabela categoria

[code](genero)
id : int 	 | auto incr | PK
nome: varchar
(categoria)
id : int 	 | auto incr | PK
nome: varchar
Então, minha classe Filme fica assim?:
public class Filme {
	private String nome;
private Genero genero;
	private Categoria categoria;
	private int id;
// construtor, getters e setters
}
E o meu Filme.hbm.xml? /// cabeçalho
<hibernate-mapping>
	<class name="pojo.Filme" table="filme">
		<id name="id" column="id" type="int">
			<generator class="native" />
		</id>
		<property name="nome" column="nome" type="string" unique="true" />
		
		<many-to-one
			name="genero"
			column="genero"
			class="pojo.Genero"
			not-null="true"
			foreign-key="FK_filme_1"/>
			
		<many-to-one
			name="categoria"
			column="categoria_filme"
			class="pojo.Categoria"
			not-null="true"
			foreign-key="FK_filme_2"/>			

	</class>
</hibernate-mapping>

Outra coisa, costumo em minhas tabelas sempre criar um pk “id” inteiro e auto incrementável. As tabelas geradas da relação n:n também devem ter esse campo como única chave estrangeira?

Mais uma outra coisa, como se chamam as classes que contém apenas os atributos e os getters e os setters? Tipo Filme... parece que pojo, to, vo???

Abraço, pessoal

15 Respostas

A

Sim, essas classes se chamam POJO (Plain Old Java Objects).

Em relacionamentos n:m o comum é ter uma tabela de relacionamento, contendo com chave primária as chaves primárias de cada uma das tabelas do relacionamento.

D

certo,

e como deve ficar minha pojo Filme? levando em conta a relação do mapeamento do hibernate

A

Sugiro que você use Annotations ao invés de arquivos de .hbm.xml.

Seu POJO filme deve ser alterar para incluir as chaves estrangeiras de gênero e categoria.

D

E como devo alterar filme pra incluir as chaves estrangeiras?

A

Acrescente uma atributo/membro na classe filme para cada chave estrangeira.

D

e já não fiz isso?

public class Filme { private String nome; private Genero genero; private Categoria categoria; private int id; // construtor, getters e setters }

Inclui objetos de cada

A

Desculpa, não tinha visto.

D

Certo, mas não entendi uma coisa.

Um objeto filme, tem um objeto genero.
Quando eu fizer o sessao.save(filme) ele deve incluir o filme e cadastrar o genero?

Genero tem um campo “id” int auto-incr, e um campo “nome” string.
Eu preciso popular apenas o campo “nome” e depois inseri-lo no objeto filme?
é isso?

Veja mais embaixo, que postei o mapeamento de Filme

A

Quanto a primeira pergunta, depende de como você tiver configurado. Normalmente você tem que registrar o gênero primeiro.

Quanto a chave primária, se o mapeamento estiver correto, é só popular os outros campos.

S

Geralmente quando você vai incluir um filme… o gênero e a categoria já existem… ou já devam existir

Afinal, no relacionamento, o

“filme é que pertence a um gênero” … e

“um filme pertence a uma categoria”

… ou seja… como se fosse um filho.
No hibernate existe uma forma de mapeamento que, pelo filho cadastra-se um pai… porém não é muito recomendada.

um abraço

Sanderson

S

Me parece que o mapeamento em filme está correto

está dando algum erro?

Sanderson

D

Dá erro sim. Tentei de diversas formas... Estou usando Struts2 e Hibernate
No form, quando eu clico em Submit, o Hibernate gera uma exceção:
org.hibernate.PropertyValueException: not-null property references a null or transient value: pojo.Filme.genero

Não entendi bem, sobre como incluir o genero no filme. O objeto Genero tem um String "nome". Eu devo digitar no form, um nome de genero que já existe no banco? Como isso é feito?

public class FilmeAction extends ActionSupport{
	private static final long serialVersionUID = 1L;
	private Filme filme;
	private FilmeDAO filmeDAO;
	private Genero genero;

	public FilmeAction() {
		this.filmeDAO = new FilmeDAO();
	}
	
	public String execute() throws Exception{
		return SUCCESS;
	}
		
	public String inserir() throws Exception{
		try {
			filme.setGenero(genero);
			filmeDAO.inserir(filme);
		}
		catch(Exception e){
			System.out.println(e);
			System.out.println("ERRO NO INSERT ERRO NO INSERT ERRO NO INSERT");
			System.out.println(genero.getNome());
			System.out.println("A CASA CAIU");
		}
		return "inserirOK";
	}
	
	public Filme getFilme() { return this.filme; }
	public void setFilme(Filme filme) { this.filme = filme; }

	public Genero getGenero() {	return this.genero; }
	public void setGenero(Genero genero) { this.genero = genero; }
	
}
FilmeForm.jsp
<s:form action="filme">
		<s:textfield label="Nome" name="filme.nome"/>
		<s:textfield label="Sinopse" name="filme.sinopse"/>
		<s:textfield label="Genero" name="genero.nome"/>
		<s:submit method="inserir"/>
	</s:form>
Genero.java
public class Genero {
	private String nome;
	private int id;
//construtor, getters e setters
S

doncopal:

Não entendi bem, sobre como incluir o genero no filme.

Genero g = generoDAO.carregarGeneroPorNome("mistério"); filme.setGenero(g); filmeDAO.salvarFilme(filme);

D

Exceção:
org.hibernate.PropertyValueException: not-null property references a null or transient value: pojo.Filme.genero

B

parceiro com o seu problema eu resolvi o meu problema… nao conseguir fazer o mapeamento
bom a dica pra vc dar um save eh:

no seu bean(POJO)

vai ter o
private Categoria categoria; certo!!

pra vc salvar é só vc salvar o campo categoria…


Filme filme = new Filme();

Categoria categoria = new Categoria();
categoria.setCodCategoria(1);

filme.setCategoria(categoria);

obs: a cetegoria de codigo um deve estar cadastrada no banco!!!
e coloca o fetch=“nome” no seu mapeamento para nao deleter a categoria!
sessao.save(filme);

Criado 23 de janeiro de 2008
Ultima resposta 2 de dez. de 2010
Respostas 15
Participantes 5