Chave composta de chave composta JPA + EclipseLink

Ola Amigos.

Estou tentando criar uma entidade que possui uma chave composta de ouma classe que tambem possui uma chave composta. Ja tentei de varias maneiras, mas o compilador mostra o erro abaixo .
“The attribute matching the id class attribute D3_COD does not have the correct type java.lang.String”
“There is no primary key attribute to match the id class attribute D3_LOCAL”

Necessito criar este relacionamento pois a tabela SD3 é uma tabela de movimentações e possui relacionamento coma tabela de estoques.

segue abaixo minhas classes

package entidades;

import java.io.Serializable;

import javax.persistence.Column;

public class MovimentacoesPK implements Serializable {

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

@Column(length = 30)
private String D3_COD;

@Column(length = 2)
private String D3_LOCAL;

@Column(length = 15)
private String D3_DOC;


public MovimentacoesPK() {
	//super();
	// TODO Auto-generated constructor stub
}

public MovimentacoesPK(String d3_COD, String d3_LOCAL, String d3_DOC) {
	super();
	D3_COD = d3_COD;
	D3_LOCAL = d3_LOCAL;
	D3_DOC = d3_DOC;
}

public String getD3_COD() {
	return D3_COD;
}

public void setD3_COD(String d3_COD) {
	D3_COD = d3_COD;
}

public String getD3_LOCAL() {
	return D3_LOCAL;
}

public void setD3_LOCAL(String d3_LOCAL) {
	D3_LOCAL = d3_LOCAL;
}

public String getD3_DOC() {
	return D3_DOC;
}

public void setD3_DOC(String d3_DOC) {
	D3_DOC = d3_DOC;
}

@Override
public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result + ((D3_COD == null) ? 0 : D3_COD.hashCode());
	result = prime * result + ((D3_DOC == null) ? 0 : D3_DOC.hashCode());
	result = prime * result + ((D3_LOCAL == null) ? 0 : D3_LOCAL.hashCode());
	return result;
}

@Override
public boolean equals(Object obj) {
	if (this == obj)
		return true;
	if (obj == null)
		return false;
	if (getClass() != obj.getClass())
		return false;
	MovimentacoesPK other = (MovimentacoesPK) obj;
	if (D3_COD == null) {
		if (other.D3_COD != null)
			return false;
	} else if (!D3_COD.equals(other.D3_COD))
		return false;
	if (D3_DOC == null) {
		if (other.D3_DOC != null)
			return false;
	} else if (!D3_DOC.equals(other.D3_DOC))
		return false;
	if (D3_LOCAL == null) {
		if (other.D3_LOCAL != null)
			return false;
	} else if (!D3_LOCAL.equals(other.D3_LOCAL))
		return false;
	return true;
}

}

segue entidade

package entidades;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;


@Entity
@Table(name = "SD3")
@IdClass(MovimentacoesPK.class)
public class Movimentacoes {
	@Id
	@ManyToOne
	@JoinColumns({ @JoinColumn(name = "D3_COD", referencedColumnName = "B2_COD", nullable = false),
			@JoinColumn(name = "D3_LOCAL", referencedColumnName = "B2_LOCAL", nullable = false) })
	private Estoque D3_COD;


	@Id
	@Column(length = 15)
	private String D3_DOC;


	private double D3_QUANT;

	@Column(length = 10)
	private String D3_EMISSAO;

	private double D3_CUSTO;

	@Column(length = 1)
	private String D3_ESTORNO;

	@Column(length = 3)
	private String D3_TIPO;

	private double D3_QTDPOSMOV;

	private double D3_CUSTOPOS;

	private double D3_QTDANTMOV;

	private double D3_CUSTOANT;

	@Column(length = 10)
	private String D3_DTCADASTRO;

	@Column(length = 13)
	private String D3_ALTERA;

	@Column(length = 10)
	private String D3_DTINTEG;

	public int getD3_SEQ() {
		return D3_SEQ;
	}

	public void setD3_SEQ(int d3_SEQ) {
		D3_SEQ = d3_SEQ;
	}

	public String getD3_DOC() {
		return D3_DOC;
	}

	public int getD3_DOC_Tam() {
		return 15;
	}

	public void setD3_DOC(String d3_DOC) {
		D3_DOC = d3_DOC;
	}

	public Estoque getD3_COD() {
		return D3_COD;
	}

	public int getD3_COD_Tam() {
		Produtos prod = new Produtos();
		return prod.getB1_COD_Tam();
	}

	public void setD3_COD(Estoque d3_COD) {
		D3_COD = d3_COD;
	}

	public double getD3_QUANT() {
		return D3_QUANT;
	}

	public void setD3_QUANT(double d3_QUANT) {
		D3_QUANT = d3_QUANT;
	}

	public int getD3_LOCAL_Tam() {
		return 2;
	}

	public String getD3_EMISSAO() {
		return D3_EMISSAO;
	}

	public void setD3_EMISSAO(String d3_EMISSAO) {
		D3_EMISSAO = d3_EMISSAO;
	}

	public double getD3_CUSTO() {
		return D3_CUSTO;
	}

	public void setD3_CUSTO(double d3_CUSTO) {
		D3_CUSTO = d3_CUSTO;
	}

	public String getD3_ESTORNO() {
		return D3_ESTORNO;
	}

	public int getD3_ESTORNO_Tam() {
		return 1;
	}

	public void setD3_ESTORNO(String d3_ESTORNO) {
		D3_ESTORNO = d3_ESTORNO;
	}

	public String getD3_TIPO() {
		return D3_TIPO;
	}

	public int getD3_TIPO_Tam() {
		return 3;
	}

	public void setD3_TIPO(String d3_TIPO) {
		D3_TIPO = d3_TIPO;
	}

	public double getD3_QTDPOSMOV() {
		return D3_QTDPOSMOV;
	}

	public void setD3_QTDPOSMOV(double d3_QTDPOSMOV) {
		D3_QTDPOSMOV = d3_QTDPOSMOV;
	}

	public double getD3_CUSTOPOS() {
		return D3_CUSTOPOS;
	}

	public void setD3_CUSTOPOS(double d3_CUSTOPOS) {
		D3_CUSTOPOS = d3_CUSTOPOS;
	}

	public double getD3_QTDANTMOV() {
		return D3_QTDANTMOV;
	}

	public void setD3_QTDANTMOV(double d3_QTDANTMOV) {
		D3_QTDANTMOV = d3_QTDANTMOV;
	}

	public double getD3_CUSTOANT() {
		return D3_CUSTOANT;
	}

	public void setD3_CUSTOANT(double d3_CUSTOANT) {
		D3_CUSTOANT = d3_CUSTOANT;
	}

	public String getD3_DTCADASTRO() {
		return D3_DTCADASTRO;
	}

	public void setD3_DTCADASTRO(String d3_DTCADASTRO) {
		D3_DTCADASTRO = d3_DTCADASTRO;
	}

	public String getD3_ALTERA() {
		return D3_ALTERA;
	}

	public void setD3_ALTERA(String d3_ALTERA) {
		D3_ALTERA = d3_ALTERA;
	}

	public String getD3_DTINTEG() {
		return D3_DTINTEG;
	}

	public void setD3_DTINTEG(String d3_DTINTEG) {
		D3_DTINTEG = d3_DTINTEG;
	}

}

Se alguem puder me ajudar agradeço.

Abs

Tens de usar @EmbeddedId

Ola pmlm
Tudo Bem ?
Também ja tentei efetuar o relacionamento utilizando @EmbeddedId porem sem sucesso. a classe continua apresentando o erro “Embedded ID class should not contain relationship mappings”
Pelo que IdClass e EmbeddedId são exatamente a mesma coisa a diferença é a maneira de organizar os fontes pois no idclass toda implemantação do relacionamento fica dentro da entidade e no EmbeddedId é utioizado uma classe a parte. Fiz a alteração conforme meu entendimento. Segue abaixo o fonte alterado utilizando EmbeddedId apresentando o mesmo erro. Não sei onde pode estar o erro.

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
@Embeddable
public class MovimentacoesPK implements Serializable {

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

	@ManyToOne
	@JoinColumns({ @JoinColumn(name = "D3_COD", referencedColumnName = "B2_COD", nullable = false),
			@JoinColumn(name = "D3_LOCAL", referencedColumnName = "B2_LOCAL", nullable = false) })
	private Estoque D3_COD;	

	@Column(length = 15)
	private String D3_DOC;


	public MovimentacoesPK() {
		//super();
		// TODO Auto-generated constructor stub
	}

	public MovimentacoesPK(Estoque d3_COD, String d3_LOCAL, String d3_DOC) {
		super();
		D3_COD = d3_COD;
		D3_DOC = d3_DOC;
	}

	public Estoque getD3_COD() {
		return D3_COD;
	}

	public void setD3_COD(Estoque d3_COD) {
		D3_COD = d3_COD;
	}


	public void setD3_LOCAL(String d3_LOCAL) {
	
	}

	public String getD3_DOC() {
		return D3_DOC;
	}

	public void setD3_DOC(String d3_DOC) {
		D3_DOC = d3_DOC;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((D3_DOC == null) ? 0 : D3_DOC.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		MovimentacoesPK other = (MovimentacoesPK) obj;
		if (D3_DOC == null) {
			if (other.D3_DOC != null)
				return false;
		} else if (!D3_DOC.equals(other.D3_DOC))
			return false;
		return true;
	}
}

Segue entidade
package entidades;

import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;

import javax.persistence.Table;

@Entity
@Table(name = "SD3")
public class Movimentacoes {

	@EmbeddedId
	private MovimentacoesPK D3_COD;

	private double D3_QUANT;

	@Column(length = 10)
	private String D3_EMISSAO;

	private double D3_CUSTO;

	@Column(length = 1)
	private String D3_ESTORNO;

	@Column(length = 3)
	private String D3_TIPO;

	private double D3_QTDPOSMOV;

	private double D3_CUSTOPOS;

	private double D3_QTDANTMOV;

	private double D3_CUSTOANT;

	@Column(length = 10)
	private String D3_DTCADASTRO;

	@Column(length = 13)
	private String D3_ALTERA;

	@Column(length = 10)
	private String D3_DTINTEG;
	
	
	public MovimentacoesPK getD3_COD() {
		return D3_COD;
	}

	public void setD3_COD(MovimentacoesPK d3_COD) {
		D3_COD = d3_COD;
	}

	public int getD3_DOC_Tam() {
		return 15;
	}

	public int getD3_COD_Tam() {
		Produtos prod = new Produtos();
		return prod.getB1_COD_Tam();
	}

	public double getD3_QUANT() {
		return D3_QUANT;
	}

	public void setD3_QUANT(double d3_QUANT) {
		D3_QUANT = d3_QUANT;
	}

	public int getD3_LOCAL_Tam() {
		return 2;
	}

	public String getD3_EMISSAO() {
		return D3_EMISSAO;
	}

	public void setD3_EMISSAO(String d3_EMISSAO) {
		D3_EMISSAO = d3_EMISSAO;
	}

	public double getD3_CUSTO() {
		return D3_CUSTO;
	}

	public void setD3_CUSTO(double d3_CUSTO) {
		D3_CUSTO = d3_CUSTO;
	}

	public String getD3_ESTORNO() {
		return D3_ESTORNO;
	}

	public int getD3_ESTORNO_Tam() {
		return 1;
	}

	public void setD3_ESTORNO(String d3_ESTORNO) {
		D3_ESTORNO = d3_ESTORNO;
	}

	public String getD3_TIPO() {
		return D3_TIPO;
	}

	public int getD3_TIPO_Tam() {
		return 3;
	}

	public void setD3_TIPO(String d3_TIPO) {
		D3_TIPO = d3_TIPO;
	}

	public double getD3_QTDPOSMOV() {
		return D3_QTDPOSMOV;
	}

	public void setD3_QTDPOSMOV(double d3_QTDPOSMOV) {
		D3_QTDPOSMOV = d3_QTDPOSMOV;
	}

	public double getD3_CUSTOPOS() {
		return D3_CUSTOPOS;
	}

	public void setD3_CUSTOPOS(double d3_CUSTOPOS) {
		D3_CUSTOPOS = d3_CUSTOPOS;
	}

	public double getD3_QTDANTMOV() {
		return D3_QTDANTMOV;
	}

	public void setD3_QTDANTMOV(double d3_QTDANTMOV) {
		D3_QTDANTMOV = d3_QTDANTMOV;
	}

	public double getD3_CUSTOANT() {
		return D3_CUSTOANT;
	}

	public void setD3_CUSTOANT(double d3_CUSTOANT) {
		D3_CUSTOANT = d3_CUSTOANT;
	}

	public String getD3_DTCADASTRO() {
		return D3_DTCADASTRO;
	}

	public void setD3_DTCADASTRO(String d3_DTCADASTRO) {
		D3_DTCADASTRO = d3_DTCADASTRO;
	}

	public String getD3_ALTERA() {
		return D3_ALTERA;
	}

	public void setD3_ALTERA(String d3_ALTERA) {
		D3_ALTERA = d3_ALTERA;
	}

	public String getD3_DTINTEG() {
		return D3_DTINTEG;
	}

	public void setD3_DTINTEG(String d3_DTINTEG) {
		D3_DTINTEG = d3_DTINTEG;
	}

}

Tal como o erro indica, o EmbeddedId não pode ter relações com outras entidades. Tens de ter as colunas como string na PK e depois podes ter a relação na entidade (com insertable / updatable a false)

    public class MovimentacoesPK implements Serializable {

        private String D3_COD;	
        
        private String D3_LOCAL;

        @Column(length = 15)
        private String D3_DOC;
    @Entity
    @Table(name = "SD3")
    public class Movimentacoes {

        @EmbeddedId
        private MovimentacoesPK D3_COD;

        @ManyToOne
        @JoinColumns({ @JoinColumn(name = "D3_COD", referencedColumnName = "B2_COD", nullable = false, insertable=false, updatable=false),
            @JoinColumn(name = "D3_LOCAL", referencedColumnName = "B2_LOCAL", nullable = false, insertable=false, updatable=false) })
        private Estoque D3_COD;

        private double D3_QUANT;