[Meio Resolvido] Chave composta em uma tabela de relacionamento do hibernate

Deixa eu explicar bem meu problema… Talvez alguém já tenha passado por isso, ou saiba pelo menos o caminho a seguir…

Explicando…

Eu tenho um bd legado, onde, entre outras, tenho uma tabela USUARIO e uma MAPA o relacionamento dessas tabelas é N:M, ou seja, um USUARIO pode acessar vários mapas e um MAPA pode ser acessado por vários usuarios.
Devido a esse relacionamento, o hibernate criou uma tabela de relacionamento com o nome USUARIO_MAPA, que consta somente duas colunas, USUARIOS_ID e MAPAS_ID, onde é feita a ligação das duas tabelas…

O que eu estou fazendo é o seguinte, todas essas tabelas que tenho no meu bd são mapeadas pelo hibernate por suas classes, as Entitys. Através dessas classes e seus DAOS eu estou serializando o conteúdo das tabelas em arquivos XML. Esses arquivos estão sendo utilizados como uma forma de backup e resturação desse banco, além também da possível troca de SGBD…
Eu serializo em XML e depois desserializo e persisto novamente no BD.

O meu problema é o seguinte, para gerar esse XML, eu precisei criar o entity para a tabela de relacionamentob[/b] que foi gerada pelo hibernate, porém, essa classe como tem somente dois atributos USUARIOS_ID e MAPAS_ID precisa ter uma coluna @Id. Então se eu deixo somente a coluna USUARIOS_ID com o annotation @Id, não consigo que usuários diferentes tenham acesso ao mesmo mapa… caso altere o annotation para MAPAS_ID, não consigo que um usuário tenha acesso a mais de um mapa…

Segue o cód. dessa class…

[code]import javax.persistence.Entity;
import javax.persistence.Id;

@SuppressWarnings("serial")
@Entity
public class Usuario_Mapa extends CiaEntity {

@Id
private long usuario_id;
private long mapas_id;

public Usuario_Mapa() {
	// TODO Auto-generated constructor stub
}

public long getUsuario_id() {
	return usuario_id;
}

public void setUsuario_id(long usuario_id) {
	this.usuario_id = usuario_id;
}

public long getMapas_id() {
	return mapas_id;
}

public void setMapas_id(long mapas_id) {
	this.mapas_id = mapas_id;
}

@Override
public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result + (int) (mapas_id ^ (mapas_id >>> 32));
	result = prime * result + (int) (usuario_id ^ (usuario_id >>> 32));
	return result;
}

@Override
public boolean equals(Object obj) {
	if (this == obj)
		return true;
	if (obj == null)
		return false;
	if (getClass() != obj.getClass())
		return false;
	final Usuario_Mapa other = (Usuario_Mapa) obj;
	if (mapas_id != other.mapas_id)
		return false;
	if (usuario_id != other.usuario_id)
		return false;
	return true;
}

}[/code]
Já tentei várias saídas, inclusive deixando as duas colunas com @Id, como uma chave composta… mas até agora não tive sucesso…

Alguém pode ajudar com isso?

[]'s

Ola amigo nao sei se é o q vc precisa mas eu tenho isto no meu mapeamento


package com.NASeguranca.Model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;


@Entity @Table(name="pedidocompraproduto")
public class PedidoCompraProduto {	

	@Embeddable
	public static class Id implements Serializable {
	@Column(name = "codigoPedidoCompra")
	private Long codigoPedidoCompra;
	@Column(name = "codigoProduto")
	private Long codigoProduto;
	public Id() {}
	public Id(Long codigoProduto, Long codigoNumeracaoProduto) {
	this.codigoProduto = codigoProduto;
	this.codigoPedidoCompra = codigoNumeracaoProduto;
	}
	@Override
	public boolean equals(Object o) {
	if (o != null && o instanceof Id) {
	Id that = (Id)o;
	return this.codigoProduto.equals(that.codigoProduto) &&
	this.codigoPedidoCompra.equals(that.codigoPedidoCompra);
	} else {
	return false;
	}
	}
	@Override
	public int hashCode() {
	return codigoProduto.hashCode() + codigoPedidoCompra.hashCode();
	}
	}	
	@EmbeddedId
	private Id id = new Id();	
	
	@ManyToOne
	@JoinColumn(name="codigoPedidoCompra",
	insertable = false,
	updatable = false)
	private PedidoCompra pedidoCompra;	
	
	@ManyToOne
	@JoinColumn(name="codigoProduto",
	insertable = false,
	updatable = false)	
	private Produto  produto;
	
	@Column(name = "valor")
	private Double valor;
	
	@Column(name = "quantidade")
	private int quantidade;
	
	@Column(name = "total")
	private Double total;
	
	
	

}

é um relacionamento onde a tabela de junçao tem a chave de duas outras como vc pode ver acima , sendo que as duas FK forman a Pk desta Entidade, espero que ajude
Abracos

Fala ae camarada…

Com esse exemplo que vc postou, agora to conseguindo persistir os dados na tabela com usuarios e mapas repetidos… porém quando dou um findAll() pra pegar todos os dados na tabela e gerar o XML, ele pega os objetos do tipo Usuario_Mapa vazios…

Mas já me deu uma luz… fico te devendo uma gelada… :slight_smile:

Falae de novo galerinha…

Com minha classe de relacionamento mapeando as chaves compostas da seguinte forma:

[code]import java.io.Serializable;

import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@SuppressWarnings("serial")
@Entity
public class Usuario_Mapa extends CiaEntity {

@Embeddable
public static class Id implements Serializable {

	private long usuario_id;
	private long mapas_id;

	public Id() {

	}

	public Id(long usuario_id, long mapas_id) {

		this.usuario_id = usuario_id;
		this.mapas_id = mapas_id;

	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (mapas_id ^ (mapas_id >>> 32));
		result = prime * result + (int) (usuario_id ^ (usuario_id >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final Id other = (Id) obj;
		if (mapas_id != other.mapas_id)
			return false;
		if (usuario_id != other.usuario_id)
			return false;
		return true;
	}
}

@EmbeddedId
private Id id = new Id();

@ManyToOne
@JoinColumn(name = "usuario_id", insertable = false, updatable = false)
private Usuario usuarios;

@ManyToOne
@JoinColumn(name = "mapas_id", insertable = false, updatable = false)
private Mapa mapas;

}[/code]
Eu consigo persistir os dados na tabela da maneira correta, tipo: Um User com vários mapas e um Map com vários usuários…

Porém, quando busco todos os dados na tabela pra gerar meu XML, ele vem da seguinte forma:

[code] <?xml version="1.0" encoding="UTF-8" ?>

  • <java version=“1.6.0_03” class=“java.beans.XMLDecoder”>
  • <object class=“java.util.ArrayList”>
  • <void method=“add”>
    <object class=“Usuario_Mapa” />
    </void>
  • <void method=“add”>
    <object class=“Usuario_Mapa” />
    </void>
    </object>
    </java>[/code]
    Ou seja, os dados contidos nas tabelas não são serializados.

Com minhas class da seguinte forma:

[code]import javax.persistence.Entity;
import javax.persistence.Id;

@SuppressWarnings("serial")
@Entity
public class Usuario_Mapa extends CiaEntity {

 @Id
 private long usuario_id, mapas_id;

 public Usuario_Mapa() {
	 // TODO Auto-generated constructor stub
 }

 public long getUsuario_id() {
	 return usuario_id;
 }

 public void setUsuario_id(long usuario_id) {
 this.usuario_id = usuario_id;
 }

 public long getMapas_id() {
	 return mapas_id;
 }

 public void setMapas_id(long mapas_id) {
	 this.mapas_id = mapas_id;
 }

 @Override
 public int hashCode() {
	 final int prime = 31;
	 int result = 1;
	 result = prime * result + (int) (mapas_id ^ (mapas_id &gt;&gt;&gt; 32));
	 result = prime * result + (int) (usuario_id ^ (usuario_id &gt;&gt;&gt; 32));
	 return result;
 }

 @Override
 public boolean equals(Object obj) {
	 if (this == obj)
		 return true;
	 if (obj == null)
		 return false;
	 if (getClass() != obj.getClass())
		 return false;
	 final Usuario_Mapa other = (Usuario_Mapa) obj;
	 if (mapas_id != other.mapas_id)
		 return false;
	 if (usuario_id != other.usuario_id)
		 return false;
	 return true;
 }

}[/code]
Eu não consigo persistir tabelas iguais para usuários diferentes, mas o XML é gerado da maneira correta, como vcs podem ver abaixo:

[code] <?xml version="1.0" encoding="UTF-8" ?>

  • <java version=“1.6.0_03” class=“java.beans.XMLDecoder”>
  • <object class=“java.util.ArrayList”>
  • <void method=“add”>
  • <object class=“Usuario_Mapa”>
  • <void property=“mapas_id”>
    <long>1</long>
    </void>
  • <void property=“usuario_id”>
    <long>1</long>
    </void>
    </object>
    </void>
  • <void method=“add”>
  • <object id=“Usuario_Mapa0” class=“Usuario_Mapa”>
  • <void property=“mapas_id”>
    <long>2</long>
    </void>
  • <void property=“usuario_id”>
    <long>2</long>
    </void>
    </object>
    </void>
    </object>
    </java>[/code]

A minha necessidade seria a união desses dois, lógico que descartando os dados em branco no xml gerado pela primeira class e a não permissão de persistir chaves duplicadas da segunda class…

Alguém tem alguma idéia?

Abraço

Ainda não encontrei um resolução pre esse problema…

Alguém ae pode ajudar?

[]'s