Hibernate + Annottations ---&gt PK Composta

4 respostas
insuportavel

Boa tarde passoal.

Tenho este codigo para acesso a uma tabela de produtos em um banco de dados, esta tabela tem sua PK formada por tres campos (grupo/subgrupo/embalagem), usei hibernate com anotations e consegui este resultado:

produtoPK

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Table;

@SuppressWarnings("serial")
@Embeddable
@Table(name="TBLPRODUTOPK")
public class ProdutoPK implements Serializable {
	@Column(name="grupo")
	private Long grupo;	
	@Column(name="subGrupo")
	private Long subGrupo;
	@Column(name="embalagem")
	private Long emb;

	protected ProdutoPK(){
		
	}

	public ProdutoPK(Long grupo,
					 Long subGrupo,
					 Long emb){
		this.grupo = grupo;
		this.subGrupo = subGrupo;
		this.emb = emb;
	}
	public Long getEmb() {
		return emb;
	}

	public void setEmb(Long emb) {
		this.emb = emb;
	}

	public Long getSubGrupo() {
		return subGrupo;
	}

	public void setSubGrupo(Long subGrupo) {
		this.subGrupo = subGrupo;
	}

	public Long getGrupo() {
		return grupo;
	}

	public void setGrupo(Long grupo) {
		this.grupo = grupo;
	}

	public int hashCode(){
		return grupo.hashCode() ^ subGrupo.hashCode() ^ emb.hashCode();
	}
	
	public boolean equals(Object obj){
		if(obj instanceof ProdutoPK){
			ProdutoPK prodPk = (ProdutoPK) obj;
			return grupo.equals(prodPk.grupo) && subGrupo.equals(prodPk.subGrupo) && emb.equals(prodPk.emb);
		}
		else
			return false;		
	}
}

e produto

import java.io.Serializable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
@SuppressWarnings("serial")
@Entity
@Table(name="TBLPRODUTO")
public class Produto implements Serializable{
	@EmbeddedId
	private ProdutoPK id;
	private String nomeCompleto;
	private String nomeResumido;
	private String unidade;
	private Float peso;
	protected Produto(){
		
	}
	public Produto(String nomeCompleto, 
				   String nomeResumido,
				   String unidade, 
				   Float peso,
				   Long grupo,
				   Long subGrupo,
				   Long emb){
		this.id = new ProdutoPK(grupo, subGrupo, emb);
		this.nomeCompleto = nomeCompleto;
		this.nomeResumido = nomeResumido;
		this.unidade = unidade;
		this.peso = peso;
	}
	
	public ProdutoPK getId() {
		return id;
	}
	public void setId(ProdutoPK id) {
		this.id = id;
	}
	public String getNomeCompleto() {
		return nomeCompleto;
	}
	public void setNomeCompleto(String nomeCompleto) {
		this.nomeCompleto = nomeCompleto;
	}
	public String getNomeResumido() {
		return nomeResumido;
	}
	public void setNomeResumido(String nomeResumido) {
		this.nomeResumido = nomeResumido;
	}
	public String getUnidade() {
		return unidade;
	}
	public void setUnidade(String unidade) {
		this.unidade = unidade;
	}
	public Float getPeso() {
		return peso;
	}
	public void setPeso(Float peso) {
		this.peso = peso;
	}
}

meu Dao

public class Dao<T> {
	private static Logger logger = Logger.getLogger(Dao.class);
	private Class persistentClass;
	protected Session session;
	
	public Dao(Session session, Class persistentClass) {
		this.session = session;
		this.persistentClass = persistentClass;
	}
	
	@SuppressWarnings("unchecked")
	public List<T> list(){		
		return session.createCriteria(persistentClass).list();
	}
	
	@SuppressWarnings("unchecked")
	public T load(Long id){
		logger.info("lendo" + persistentClass + " com id "+id);
		return (T) session.load(persistentClass, id);		
	}
	
	public void save(T t) {
		logger.info("salvando " + t);
		session.save(t);
	}
	
	public void delete(T t){
		logger.info("removendo " + t);
		session.delete(t);
	}
	
	protected Session getSession(){
		return session;		
	}

	public void saveOrUpdate(T t) {
		session.saveOrUpdate(t);
	}
	
	public void update(T t){
		logger.info("atualizando " + t);
		session.update(t);
	}
}

e para fazer um teste, estou com esta classe aqui:

public class TestaDaoLoad {
	public static void main(String[] args) {
		Session session = HibernateSessionFactory.getSession();
		Dao<Produto> produtoDao = new Dao<Produto>(session, Produto.class);

		Produto produto = produtoDao.load(1L);
		System.out.println(" Produto " + produto.getNomeResumido());
		
	}
}

e ela esta me retornando esta exception

19:28:11,125  INFO HibernateSessionFactory:20 - abrindo uma nova sessão
19:28:11,281  INFO Dao:30 - lendoclass br.com.dovac.modelo.Produto com id 1
Exception in thread "main" org.hibernate.PropertyAccessException: could not get a field value by reflection getter of br.com.dovac.modelo.ProdutoPK.grupo
	at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:35)
	at org.hibernate.tuple.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:58)
	at org.hibernate.tuple.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:64)
	at org.hibernate.tuple.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:76)
	at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:307)
	at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:158)
	at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:104)
	at org.hibernate.engine.EntityKey.<init>(EntityKey.java:48)
	at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:75)
	at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:871)
	at org.hibernate.impl.SessionImpl.load(SessionImpl.java:788)
	at org.hibernate.impl.SessionImpl.load(SessionImpl.java:781)
	at br.com.dovac.dao.Dao.load(Dao.java:31)
	at br.com.dovac.executavel.TestaDaoLoad.main(TestaDaoLoad.java:15)
Caused by: java.lang.IllegalArgumentException
	at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(Unknown Source)
	at sun.reflect.UnsafeObjectFieldAccessorImpl.get(Unknown Source)
	at java.lang.reflect.Field.get(Unknown Source)
	at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:32)
	... 13 more

Alguem pode apontar o meu erro e me ajudar a resolver este problema?

4 Respostas

E

Fala ai cara, eu tb estou com o mesmo problema, eu tenho um relacionamento muito para muito, então eu criei uma terceira tabela que tem como chave primaria as chaves da outras duas originando chave primaria e chave estrangeira, não como posso resolver esse relacionamento usando Hibernate Annottations. será que vc pode me dar uma luz

sds,
Eduardo

francofabio

olá “insuportavel”!

Seu prob. eh pq a PK da sua classe produto eh um objeto do tipo ProdutoPK, logo quando vc for fazer um get ou load do produto vc deve passar como id um objeto ProdutoPK e ñ um Long, altere seu Dao para suportar “ID’s” diferentes de Long.
Sugestão:

public class Dao<T, PK extends Serializable>{

   .
   .
   .

   public T load(PK id){
         
   }

   .
   .
   .

}
insuportavel

Opa, fala ai francofabio.

Vou fazer isto e vamos ver se muda a situação.

E peguei este exemplo e estava tentando usar, eu consegui de outra forma, mas vamos ver com a solução que vc esta indicando!

Valeu! :wink:

francofabio

tenta ai e posta o resultado…
t+

Criado 11 de dezembro de 2006
Ultima resposta 21 de dez. de 2006
Respostas 4
Participantes 3