Problemas Hibernate Annotation ManyToMany e OneToOne(pk sendo fk)

Pessoal blzinha?

Estou fazendo mapeamentos com hibernate annotation e estou enfretando algumas dificuldades, tanto no oneToOne quanto no ManyToMany.
Segue abaixo elas:

[color=brown]1- Tenho duas classes, PC e placaMae, elas estao persistindo perfeitamente, como podem ver o mapeamento e de 1 para 1.[/color]

@Entity
@Table(name="Pc",schema="annotation")
public class PC extends BeanAbstrato implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Id
	private Integer id;
	
	@Column(name="nome",length=50)
	private String nome;
	
	@Column(name="preco",precision=20,scale=2)
	private BigDecimal preco;
	
	@OneToOne(cascade=CascadeType.PERSIST)
	@JoinColumn(nullable=false)
	private PlacaMae placaMae;
	
	public PC(Integer id, String nome, BigDecimal preco, PlacaMae placaMae) {
		super();
		this.id = id;
		this.nome = nome;
		this.preco = preco;
		this.placaMae = placaMae;
	}

	public PC() {
		
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public BigDecimal getPreco() {
		return preco;
	}

	public void setPreco(BigDecimal preco) {
		this.preco = preco;
	}

	public PlacaMae getPlacaMae() {
		return placaMae;
	}

	public void setPlacaMae(PlacaMae placaMae) {
		this.placaMae = placaMae;
	}
	
	
}

@Entity
@Table(name="PlacaMae",schema="annotation")
public class PlacaMae extends BeanAbstrato implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Id
	private Integer id;

	@Column(name="marca",length=50)
	private String marca;
	
	@Temporal(TemporalType.DATE)
	@Column(name="fabricacao",nullable=false)
	private Date fabricacao;
	
	@Column(name="preco",nullable=false,precision=20,scale=2)
	private BigDecimal preco;
	
	public PlacaMae() {
		
	}

	public PlacaMae(Integer id, String marca, Date fabricacao, BigDecimal preco) {
		this.id = id;
		this.marca = marca;
		this.fabricacao = fabricacao;
		this.preco = preco;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getMarca() {
		return marca;
	}

	public void setMarca(String marca) {
		this.marca = marca;
	}

	public Date getFabricacao() {
		return fabricacao;
	}

	public void setFabricacao(Date fabricacao) {
		this.fabricacao = fabricacao;
	}

	public BigDecimal getPreco() {
		return preco;
	}

	public void setPreco(BigDecimal preco) {
		this.preco = preco;
	}	
	
}

A minha duvida é como faco para que o id da minha classe PC seja FK vindo de PlacaMae??Gostaria que tivesse em PC uma chave primaria simples, sendo ela o id de placaMae.
Eu estou pesquisando isso a algumas semanas, e peço a gentileza, se puderem me ajudar com exemplos, referencias, de qualquer forma.

[color=brown]2- Como podem ver abaixo, tenho duas classes, Aluno e Curso, o relacionamento entre elas e n para n.[/color]

@Entity
@Table(name="aluno")
public class Aluno extends BeanAbstrato implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Id
	private Integer id;
	
	@Column(name="nome",nullable=false,length=50)
	private String nome;
	
	@Column(name="matricula",nullable=false)
	@Temporal(TemporalType.DATE)
	private Date matricula;
	
	@Column(name="endereco",nullable=false,length=100)
	private String endereco;
	
	public Aluno() {
		
	}

	public Aluno(Integer id, String nome, Date matricula, String endereco) {
		super();
		this.id = id;
		this.nome = nome;
		this.matricula = matricula;
		this.endereco = endereco;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public Date getMatricula() {
		return matricula;
	}

	public void setMatricula(Date matricula) {
		this.matricula = matricula;
	}

	public String getEndereco() {
		return endereco;
	}

	public void setEndereco(String endereco) {
		this.endereco = endereco;
	}	
}


@Entity
@Table(name="curso")
public class Curso extends BeanAbstrato implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Id
	private Integer id;
	
	@Column(name="nome",nullable=false,length=30)
	private String nome;
	
	@Column(name="descricao",nullable=false,length=30)
	private String descricao;
	
	@Column(name="cargahoraria",nullable=false,length=4)
	private Integer cargahoraria;
	
	@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
	@JoinTable(name="curso_aluno",schema="annotation",
			joinColumns={@JoinColumn(name="cursos_id")},
			inverseJoinColumns={@JoinColumn(name="alunod_id")})
	private Set<Aluno> alunos = new HashSet<Aluno>();
	
	public Curso() {
		
	}

	public Curso(Integer id, String nome, String descricao, Integer cargahoraria,
			Set<Aluno> alunos) {
		super();
		this.id = id;
		this.nome = nome;
		this.descricao = descricao;
		this.cargahoraria = cargahoraria;
		this.alunos = alunos;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public Integer getCargahoraria() {
		return cargahoraria;
	}

	public void setCargahoraria(Integer cargahoraria) {
		this.cargahoraria = cargahoraria;
	}

	public Set<Aluno> getAlunos() {
		return alunos;
	}

	public void setAlunos(Set<Aluno> alunos) {
		this.alunos = alunos;
	}

}

Esse e o script que estou utilizando para a criacao das tabelas no PostGresql:

create table curso(
id integer not null,
descricao varchar(30) not null,
cargahoraria int4 not null,
nome varchar(30) not null,
primary key(id)
);

create table aluno(
id integer not null,
matricula date not null,
endereco varchar(100) not null,
nome varchar(50) not null,
primary key(id)
);

create table curso_aluno(
cursos_id integer not null,
alunos_id integer not null,
primary key(cursos_id,alunos_id),
foreign key(cursos_id) references curso(id),
foreign key(alunos_id) references aluno(id)
);

A persistencia nas entidades Aluno e Curso esta ocorrendo perfeitamente, minha duvida é, como faço para que seja feito a persistencia na entidade curso_aluno
sempre que for inserido um aluno ou curso, ou ambos?qual é a forma mais correta disto ocorrer?Não é necessario eu criar um bean para essa entidade né??

Agradeço a atençao de todos

Simples… sua classe placamae deve ser “implements Serializable”

e em PC fica assim:



@EmbeddedId
private PlacaMae id;

Muito obrigado lauronolasco, deu certo aqui, mas se eu quiser fazer com que em minha tabela a unica pk seja fk é mesma coisa?

Ah quanto a minha duvida 2, pode esclarecer?

muito obrigado

abraço

bom se a sua segunda duvida se refere ao mapeamento da classe CursoAluno…

Crie uma classe a parte para implementar uma PK:

public class PkCurAlu implements Serializable{

     // anotacoes para fk
     Curso curso;

     // anotacoes para fk
     Aluno aluno;

 // construtor

  // get .. set ..

}

e na sua classe CursoAluno:

public class CursoAluno{

@EmbeddedId
PkCurAlu pk;


// .... as outras fields

// construtor

  // get .. set ..


}

[quote]Muito obrigado lauronolasco, deu certo aqui, mas se eu quiser fazer com que em minha tabela a unica pk seja fk é mesma coisa?
[/quote]

é sim…

lauronolasco , fiz como vc informou, apenas implementei essas duas classes, que segue a mesma ideia das citadas anteriormente, acrescentei apenas o atributo @Embeddable na classe dona da fk, me corriga se estiver errado.
o problema e que quando tento efetuar a persistencia de Aparelho, me ocorre o erro:

[color=brown]ERROR: column “numero” of relation “aparelho” does not exist[/color]

ps:lembrando que dessa forma a persistencia de Numero e feita normalmente
Sem o atributo @Embeddable na classe Numero o erro é o mesmo

Segue abaixo as classes e o script para a criacao da tabela no BD:

@Entity
@Table(name="Numero",schema="annotation")
@Embeddable
public class Numero extends BeanAbstrato implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Id
	private Integer id;
	
	@Column(name="numero",nullable=true)
	private Integer numero;
	
	public Numero() {
		
	}

	public Numero(Integer id, Integer numero) {
		super();
		this.id = id;
		this.numero = numero;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Integer getNumero() {
		return numero;
	}

	public void setNumero(Integer numero) {
		this.numero = numero;
	}
	
	@Override
	public boolean equals(Object arg0) {
		// TODO Auto-generated method stub
		return super.equals(arg0);
	}
	
	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return super.hashCode();
	}
}


@Entity
@Table(name="Aparelho",schema="annotation")
public class Aparelho extends BeanAbstrato implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@EmbeddedId
	@OneToOne(cascade=CascadeType.PERSIST)
	@JoinColumn(nullable=false)
	private Numero numero;
		
	@Column(name="modelo",nullable=false,length=30)
	private String modelo;
	
	public Aparelho() {
		
	}	
	
	public Aparelho(Numero numero, String modelo) {
		super();
		this.numero = numero;
		this.modelo = modelo;
	}

	public Numero getNumero() {
		return numero;
	}

	public void setNumero(Numero numero) {
		this.numero = numero;
	}

	public String getModelo() {
		return modelo;
	}

	public void setModelo(String modelo) {
		this.modelo = modelo;
	}	
	
	@Override
	public boolean equals(Object arg0) {
		// TODO Auto-generated method stub
		return super.equals(arg0);
	}
	
	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return super.hashCode();
	}
}

Classe principal que executa a operacao de persistencia:

public class ExecutaOneToOnePK_e_FK {

	public static void main(String[] args) {
		Aparelho aparelho = new Aparelho();
		Numero numero = new Numero();
		
		numero.setId(2);
		numero.setNumero(99851291);
		
		aparelho.setNumero(numero);
		aparelho.setModelo("Motorolla");
		
		
		try {
			HibernateUtil.save(numero);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

script para criacao do BD:

create table numero (
id integer,
numero integer null,
primary key(id)
);

create table aparelho (
idNumero integer not null,
modelo varchar(30) not null,
primary key(idNumero),
foreign key(idNumero) references numero(id)
);

Sabe me dizer o pq que esta ocorrendo este erro???

Agradeço desde já

Pessoal, por favor, alguem pode me ajudar com esse problema???

detalhe… como vc nao especificou a o nome da coluna ‘numero no @JoinColumn’ ele pegou por padrao o nome ‘numero’…

no erro diz q numero nao existe em aparelho… da uma olhada no bando e ve o nome da coluna

lauronolasco fiz isso mas nao resolveu o problema.
pelo que percebi, ele não está pegando o id da classe numero como pk, esta pegando o campo numero da tabela, pois no momento do insert gerado no console, ele faz insert into aparelho(modelo,numero) values(“motorolla”,99851291), ele esta se perdendo nesse momento…

lauronolasco conseguir resolver o problema, tive de criar uma classe que representasse a pk, e ai sim anota-la com @Embeded, e a classe aparelho, coloquei a instancia dessa classe com a anotação @EmbededId, ai funfou…

agora outra duvida, tenho um relacionamento ManyToMany, entre curso e departamento, gerando a tabela associativa curso_departamento, gostaria que sempre que fosse inserido um curso ou departamento fosse inserido na tabela associativa…como faço isso???

agradeço desde já

Alguem pode me ajudar?

Tks

Pessoal isso é tão complicado assim?

por favor, quem puder me ajudar…

Vlws