Problema com mapeamento ManyToOne com chave composta

2 respostas
felipedamiani

Boa noite pessoal,
estou tendo problema ao tentar remover uma entidade do bd, talves seja mapeamento errado, se for por favor, me corrijam.
Abaixo Tenho minha Entidade Principal: Area.java

package br.com.biflex.business.entity;

import java.io.Serializable;

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

@Entity
@Table(name="area")
public class Area implements Serializable {

	private static final long serialVersionUID = 1L;
	
	@EmbeddedId
	private AreaPK pk;
	
	@ManyToOne (fetch = FetchType.EAGER)
	@JoinColumn (name = "id_uf", referencedColumnName = "id_uf", insertable = false, updatable = false)
	private Uf uf;
	
	@Column(name = "nom_cidade", nullable = false, length = 50)
	private String nomCidade;
	
	@Column(name = "num_codigo", nullable = false)
	private Integer numCodigo;

	public Area(){

	}

	public Area(AreaPK pk, Uf uf, String nomCidade, Integer numCodigo) {
		super();
		this.pk = pk;
		this.uf = uf;
		this.nomCidade = nomCidade;
		this.numCodigo = numCodigo;
	}

	public AreaPK getPk() {
		if (pk == null) {
			pk = new AreaPK();
		}
		return pk;
	}

	public void setPk(AreaPK pk) {
		this.pk = pk;
	}

	public Uf getUf() {
		if (uf == null) {
			uf = new Uf();
		}
		return uf;
	}

	public void setUf(Uf uf) {
		this.uf = uf;
	}

	public String getNomCidade() {
		return nomCidade;
	}

	public void setNomCidade(String nomCidade) {
		this.nomCidade = nomCidade;
	}

	public Integer getNumCodigo() {
		return numCodigo;
	}

	public void setNumCodigo(Integer numCodigo) {
		this.numCodigo = numCodigo;
	}

}

E aqui a Primary Key:

package br.com.biflex.business.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Transient;

@Embeddable
public class AreaPK implements Serializable {

	@Transient
	private static final long serialVersionUID = 1L;
	
	@Column(name="id_area")
	private Integer idArea;

	public AreaPK(){

	}

	public AreaPK(Integer idArea) {
		super();
		this.idArea = idArea;
	}

	public Integer getIdArea() {
		return idArea;
	}

	public void setIdArea(Integer idArea) {
		this.idArea = idArea;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((idArea == null) ? 0 : idArea.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;
		final AreaPK other = (AreaPK) obj;
		if (idArea == null) {
			if (other.idArea != null)
				return false;
		} else if (!idArea.equals(other.idArea))
			return false;
		return true;
	}

}

Pois bem, quando vou excluir ou atualizar esta entidade, me retorna o seguinte erro:

21:25:43,561 ERROR [STDERR] javax.ejb.EJBException: javax.persistence.EntityNotFoundException: Unable to find br.com.biflex.business.entity.Uf with id br.com.biflex.business.entity.UfPK@1f
21:25:43,561 ERROR [STDERR] 	at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:63)
21:25:43,561 ERROR [STDERR] 	at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83)

Minha entidade Uf.java

package br.com.biflex.business.entity;

import java.io.Serializable;

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

@Entity
@Table(name="uf")
public class Uf implements Serializable {

	@Transient
	private static final long serialVersionUID = 1L;
	
	@EmbeddedId
	private UfPK pk;
	
	@Column(name = "nom_estado", nullable = false, length = 50)
	private String nomEstado;
	
	@Column(name = "nom_sigla", nullable = false, length = 50)
	private String nomSigla;

	public Uf(){

	}

	public Uf(UfPK pk, String nomEstado, String nomSigla) {
		super();
		this.pk = pk;
		this.nomEstado = nomEstado;
		this.nomSigla = nomSigla;
	}

	public UfPK getPk() {
		if (pk == null) {
			pk = new UfPK();
		}
		return pk;
	}

	public void setPk(UfPK pk) {
		this.pk = pk;
	}

	public String getNomEstado() {
		return nomEstado;
	}

	public void setNomEstado(String nomEstado) {
		this.nomEstado = nomEstado;
	}

	public String getNomSigla() {
		return nomSigla;
	}

	public void setNomSigla(String nomSigla) {
		this.nomSigla = nomSigla;
	}

}

E a primary key dela: UfPK.java

package br.com.biflex.business.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Transient;

@Embeddable
public class UfPK implements Serializable {

	@Transient
	private static final long serialVersionUID = 1L;
	
	@Column(name="id_uf")
	private Integer idUf;

	public UfPK(){

	}

	public UfPK(Integer idUf) {
		super();
		this.idUf = idUf;
	}

	public Integer getIdUf() {
		return idUf;
	}

	public void setIdUf(Integer idUf) {
		this.idUf = idUf;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((idUf == null) ? 0 : idUf.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;
		final UfPK other = (UfPK) obj;
		if (idUf == null) {
			if (other.idUf != null)
				return false;
		} else if (!idUf.equals(other.idUf))
			return false;
		return true;
	}

	

}

e meus métodos do GenericDao:

public T save(T entidade) throws Exception {
		return em.merge(entidade);
	}

	public void update(T entidade) throws Exception {
		entidade = em.merge(entidade);
	}

	public void delete(T entidade) throws Exception {
		em.remove(em.merge(entidade));
	}

Alguém sabe me dizer se é problema no mapeamento, ou qual motivo do erro descrito??
Já dei uma pesquisada aqui mais não consegui nada.

Abraços

2 Respostas

joede.fadel

Eu achei a forma que vc cria chave primária meio estranha, pois você desenvolve uma classe apenas para isso, essa tecnica é utililzada quando é chave composta e no seu código não identifiquei nenhuma classe composta.

com relação ao erro na linha 23

não tem nenhum atributo id_uf na sua classe UF mais sim um atributo pk

@EmbeddedId  
private UfPK pk;

no referencedColumnName você não faz referência ao nome da coluna do banco mais sim da sua classe

felipedamiani

Olá Joede, obrigado pela resposta, bom neste exemplo realmente não tem chave composta, mais em alguns casos vou precisar usar, porisso adotei este padrão,
vou alterar o mapeamento conforme vc sugerio. Depois posto os resultados…

Até

Criado 16 de novembro de 2009
Ultima resposta 17 de nov. de 2009
Respostas 2
Participantes 2