[RESOLVIDO] JPA c/ Hibernate - 2 tabs, N aluno p/ 1 professor, sem erros + n cria corretamente

16 respostas
A
package br.com.escola.entity;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="tb_pai")
public class Pai {

	@Id
	@GeneratedValue
	private Integer idPai;
	private String nome;
	
    @OneToMany(cascade = {CascadeType.PERSIST}) 
	private List<Aluno> alunos = new ArrayList<Aluno>();

	public void setAlunos(List<Aluno> alunos) {
		this.alunos = alunos;
	}
	
	public List<Aluno> getAlunos() {
		return alunos;
	}
	
	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getNome() {
		return nome;
	}

	public void setIdPai(Integer idPai) {
		this.idPai = idPai;
	}

	public Integer getIdPai() {
		return idPai;
	}
}

package br.com.escola.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity 
@Table(name="tb_aluno")
public class Aluno {

	@Id
	@GeneratedValue
	private Integer idAluno;
	
	private Integer idPai;
	
    @JoinColumn(name="idPai", referencedColumnName = "idPai", insertable = false, updatable = false) //@JoinColumn(name="idPai") 
	@ManyToOne
	private Pai pai;

	public Integer getIdAluno() {
		return idAluno;
	}

	public void setIdAluno(Integer idAluno) {
		this.idAluno = idAluno;
	}

	public Integer getIdPai() {
		return idPai;
	}

	public void setIdPai(Integer idPai) {
		this.idPai = idPai;
	}

	public Pai getPai() {
		return pai;
	}

	public void setPai(Pai pai) {
		this.pai = pai;
	}
} 

package br.com.escola.teste;

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;


public class Teste {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("Escola");
		factory.close();
	}
}

16 Respostas

A

Ele gera três tabelas mas não funcionam adequadamente. Vide anexo:

A

TENTEI TAMBÉM DA SEGUINTE MANEIRA:

package br.com.escola.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity 
@Table(name="tb_aluno")
public class Aluno {

	@Id
	@GeneratedValue
	private Integer idAluno;
	
	private Integer idPai;
	
    @JoinColumn(name="idPai", referencedColumnName = "idPai", insertable = false, updatable = false) //@JoinColumn(name="idPai") 
	@ManyToOne
	private Pai pai;

	public Integer getIdAluno() {
		return idAluno;
	}

	public void setIdAluno(Integer idAluno) {
		this.idAluno = idAluno;
	}

	public Integer getIdPai() {
		return idPai;
	}

	public void setIdPai(Integer idPai) {
		this.idPai = idPai;
	}

	public Pai getPai() {
		return pai;
	}

	public void setPai(Pai pai) {
		this.pai = pai;
	}
}
package br.com.escola.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="tb_pai")
public class Pai {

	@Id
	@GeneratedValue
	private Integer idPai;
	private String nome;
	
	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getNome() {
		return nome;
	}

	public void setIdPai(Integer idPai) {
		this.idPai = idPai;
	}

	public Integer getIdPai() {
		return idPai;
	}
}

Daí ele criou duas tabelas, porém o relacionamento não funcionando corretamente.

A

O QUE EQUIVALENTE NO SQL É:

CREATE TABLE `escola`.`tbl_aluno` ( `idAluno` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, `nomeAluno` VARCHAR(45) NOT NULL, `idPaiFk` INTEGER UNSIGNED NOT NULL, PRIMARY KEY (`idAluno`), CONSTRAINT `idPaiFk` FOREIGN KEY `idPaiFk` (`idPaiFk`) REFERENCES `tbl_pai` (`idPai`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB;

J

Dá primeira vez, ele criou as 2 tabelas, porque você fez o relacionamento dos dois lados. Tanto no lado Pai, quanto no lado Aluno. Quando você coloca assim, ele entende que são relacionamentos independentes (não tem relação um com o outro), ai nesse caso, você precisa usar dentro da anotation a propriedade mappedBy, dessa forma, o hibernate entende que apesar do relacionamento estar dos dois lados, é o mesmo relacionamento e não cria a tabela auxiliar e sim a chave estrangeira. Não tô em casa, se não te ajudava com algum exemplo…

Mas da segunda maneira, deveria funcionar corretamente. Mesmo deletando o banco e mandando o hibernate criar, ele continua criando uma tabela auxiliar?

A

Olá, valeu pela ajuda…

Pois é, pensei o mesmo que dá segunda maneira, foi a primeira maneira que tentei mas não funcionou, recrei a base de dados com o Hibernate JPA e nada…

Vou testar usando o mappedBy…

A

REALMENTE... ISSO DEVERIA FUNCIONAR, EU ACHO:

package br.com.escola.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity 
@Table(name="tb_aluno")
public class Aluno {

	@Id
	@GeneratedValue
	private Integer idAluno;
	
	private Integer idPai;
	
    @JoinColumn(name="idPai", referencedColumnName = "idPai", insertable = false, updatable = false, nullable = false) //@JoinColumn(name="idPai") 
	@ManyToOne
	private Pai pai;

	public Integer getIdAluno() {
		return idAluno;
	}

	public void setIdAluno(Integer idAluno) {
		this.idAluno = idAluno;
	}

	public Integer getIdPai() {
		return idPai;
	}

	public void setIdPai(Integer idPai) {
		this.idPai = idPai;
	}

	public Pai getPai() {
		return pai;
	}

	public void setPai(Pai pai) {
		this.pai = pai;
	}
}
A

FIZ PEQUENAS MUDANÇAS, MESMO ASSIM CONTINUA NÃO FUNCIONANDO O RELACIONAMENTO, NAO É CRIADA A CHAVE ESTRANGEIRA CORRETAMENTE:

package br.com.escola.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity 
@Table(name="tb_aluno")
public class Aluno {

	@Id
	@GeneratedValue
	private Integer idAluno;
	private Integer idPaiFk;
	private String nome;
	
    @JoinColumn(name="idPaiFk",
    			referencedColumnName = "idPai", 
    			insertable = false, 
    			updatable = false, 
    			nullable = false
    ) 
	@ManyToOne
	private Pai pai = new Pai();

	public Integer getIdAluno() {
		return idAluno;
	}

	public void setIdAluno(Integer idAluno) {
		this.idAluno = idAluno;
	}

	public Integer getIdPaiFk() {
		return idPaiFk;
	}

	public void setIdPaiFk(Integer idPaiFk) {
		this.idPaiFk = idPaiFk;
	}

	public Pai getPai() {
		return pai;
	}

	public void setPai(Pai pai) {
		this.pai = pai;
	}
	
	public void setNome(String nome) {
		this.nome = nome;
	}
	
	public String getNome() {
		return nome;
	}
}
A

MAIS TENTATIVAS:

package br.com.escola.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity 
@Table(name="tb_aluno")
public class Aluno {

	@Id
	@GeneratedValue
	private Integer idAluno;
	//private Integer idPaiFk;
	private String nome;
	
    /*@JoinColumn(name="idPaiFk",
    			referencedColumnName = "pai.idPai", 
    			insertable = false, 
    			updatable = false, 
    			nullable = false
    ) */
	@ManyToOne
	private Pai pai = new Pai();

	public Integer getIdAluno() {
		return idAluno;
	}

	public void setIdAluno(Integer idAluno) {
		this.idAluno = idAluno;
	}

/*	public Integer getIdPaiFk() {
		return idPaiFk;
	}

	public void setIdPaiFk(Integer idPaiFk) {
		this.idPaiFk = idPaiFk;
	}*/

	public Pai getPai() {
		return pai;
	}

	public void setPai(Pai pai) {
		this.pai = pai;
	}
	
	public void setNome(String nome) {
		this.nome = nome;
	}
	
	public String getNome() {
		return nome;
	}
}
J

Vou te mostrar um exemplo que tenho aqui.

Tenho uma entidade Conta e uma Movimentação. Cada Movimentação é referente a uma Conta (chave estrangeira). Mapeie da seguinte maneira:

@Entity
public class Movimentacao {

// outros atributos

@ManyToOne
	private Conta conta;

//getters and setters
}

E para poder ter uma lista de movimentações por conta, está da seguinte maneira:

@Entity
public class Conta {

//outros atributos
	@OneToMany(mappedBy="conta")
	private List&lt;Movimentacao&gt; movimentacoes = new ArrayList&lt;Movimentacao&gt;();

}

Ele cria como chave estrangeira. No mappedBy você coloca o lado fraco da relação. Movimentação é o lado forte, já que ela tem uma relação com Conta, mas Conta não tem com ela (conceito de chave estrangeira)

Vê se te ajuda.

Observação, dá um drop database, e faz um modelo simples só para testar isso, se funcionar, depois coloca no seu projeto

A

Puxa que estranho, continua não funcionando… Fiz do jeitinho que você falou…

A
package br.com.escola.entity;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="tb_pai")
public class Pai {

	@Id
	@GeneratedValue
	private Integer idPai;
	private String nome;
	
	@OneToMany(mappedBy="pai")
	List<Aluno> alunosList = new ArrayList<Aluno>();
	
	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getNome() {
		return nome;
	}

	public void setIdPai(Integer idPai) {
		this.idPai = idPai;
	}

	public Integer getIdPai() {
		return idPai;
	}
	
	public void setAlunosList(List<Aluno> alunosList) {
		this.alunosList = alunosList;
	}
	
	public List<Aluno> getAlunosList() {
		return alunosList;
	}
}
package br.com.escola.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity 
@Table(name="tb_aluno")
public class Aluno {

	@Id
	@GeneratedValue
	private Integer idAluno;
	//private Integer idPaiFk;
	private String nome;
	
    /*@JoinColumn(name="idPaiFk",
    			referencedColumnName = "pai.idPai", 
    			insertable = false, 
    			updatable = false, 
    			nullable = false
    ) */
	@ManyToOne
	//@JoinColumn(name="idPai")
	private Pai pai;

	public Integer getIdAluno() {
		return idAluno;
	}

	public void setIdAluno(Integer idAluno) {
		this.idAluno = idAluno;
	}

/*	public Integer getIdPaiFk() {
		return idPaiFk;
	}

	public void setIdPaiFk(Integer idPaiFk) {
		this.idPaiFk = idPaiFk;
	}*/

	public Pai getPai() {
		return pai;
	}

	public void setPai(Pai pai) {
		this.pai = pai;
	}
	
	public void setNome(String nome) {
		this.nome = nome;
	}
	
	public String getNome() {
		return nome;
	}
}
J

Posta ai teu persistence.xml

Se a propriedade hibernate.hbm2ddl.auto tiver como update, ele cria a chave primária, mas não apaga a tabela auxiliar. Já tentou dropar o banco e criar novamente?

Você não está usando nenhum mapeamento em xml também né? Apenas por anottations correto?

A
javablue:
Posta ai teu persistence.xml

Se a propriedade hibernate.hbm2ddl.auto tiver como update, ele cria a chave primária, mas não apaga a tabela auxiliar. Já tentou dropar o banco e criar novamente?

Você não está usando nenhum mapeamento em xml também né? Apenas por anottations correto?

Estava create, mas dropei as tabelas e as criei usando update e não funcionou. Não há tabela auxiliar. Já dropei a base de dados e nada. Estou
usando puramente anotação. Vide meu persistence.xml:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;persistence xmlns="http://java.sun.com/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
	version="1.0"&gt;

	&lt;persistence-unit name="Escola" transaction-type="RESOURCE_LOCAL"&gt;
		&lt;provider&gt;
			org.hibernate.ejb.HibernatePersistence
		&lt;/provider&gt;
		&lt;properties&gt;
			&lt;property name="hibernate.dialect" value="org.hibernate.dialect.MySQLMyISAMDialect" /&gt;
			&lt;property name="hibernate.hbm2ddl.auto" value="update" /&gt;
			&lt;property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /&gt;
			&lt;property name="javax.persistence.jdbc.user" value="root" /&gt;
			&lt;property name="javax.persistence.jdbc.password" value="root" /&gt;
			&lt;property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/Escola" /&gt;
		&lt;/properties&gt;
	&lt;/persistence-unit&gt;
&lt;/persistence&gt;
A

Puxa, acho que agora está funcionando, fiz uma mudança no persistence.xml para:

Testando…

A

JavaBlue, problema solucionado, era aquela linha mesma, questões de MyISAM (sem relacionamento) você deu a dica do persistence.xml e acabei matando a charada rs. Valeu mesmo kra. Abração.

AS.

J

Só consegui entrar no guj agora.

Quando vi teu persistence.xml, também ia sugerir isso.

Que bom que funcionou

Criado 15 de maio de 2011
Ultima resposta 16 de mai. de 2011
Respostas 16
Participantes 2