Chave primária com dois campos [HIBERNATE]

12 respostas
juceliohv

Boa tarde!

Tenho uma tabela em MySql que possui como chave primária dois campos String.

Preciso necessáriamente criar um mapeamento para o objeto indicando uma chave composta no mapeamento do objeto .hbm?

12 Respostas

Grinvon

Você terá que usá-la como Composite ID.

Veja um exemplo aqui.

juceliohv

Existe outra forma sem precisar criar um objeto que represente a chave?

Por que fica estranho, como você vai trabalhar com estes objetos na hora de criá-los?

Kanin_Dragon

Grinvon:
Você terá que usá-la como Composite ID.
Veja um exemplo aqui.

Jovem,

Utlizar o Composite ID é uma boa prática.

Conselho não fuja desta implementação;

abs,

juceliohv

Então como devo proceder?

Quero dizer, como instancio um objeto que possui outra classe para representar a chave primária?

R

Supondo que a classe Entidade tem uma chave composta com dois elementos do tipo String, e que essa chave composta foi modelada numa classe chamada IdEntidade():

Entidade entidade = new Entidade();
entidade.setId(new IdEntidade());
entidade.getId().setCampo1("12");
entidade.getId().setCampo2("34");
juceliohv

Até ai tudo bem, o problema é quando coloco pra rodar.

Segue.

11/05/2011 15:42:22 org.hibernate.cfg.Configuration doConfigure INFO: Configured SessionFactory: null Initial SessionFactory creation failed.org.hibernate.PropertyNotFoundException: Could not find a getter for mensagemPK.NrValidac in class Persistencia.AvalMsg Exception in thread "AWT-EventQueue-0" java.lang.ExceptionInInitializerError at Persistencia.util.HibernateUtil.<clinit>(HibernateUtil.java:36) at Persistencia.AvalMsgDAO.createRecord(AvalMsgDAO.java:41) at gui.ManutencaoDeMensagens.saveRecord(ManutencaoDeMensagens.java:882) at gui.ManutencaoDeMensagens.jB_saveActionPerformed(ManutencaoDeMensagens.java:762) at gui.ManutencaoDeMensagens.access$1000(ManutencaoDeMensagens.java:31) at gui.ManutencaoDeMensagens$12.actionPerformed(ManutencaoDeMensagens.java:437) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)

Segue classe.

package Persistencia;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.annotations.Entity;
import org.hibernate.annotations.Table;

import util.ErrorMessage;

public class AvalMsg {	
    private AvalMsgPK mensagemPK;
    private int    criticidade;
    private String erp;
    private String DescrAnalis;
    private String DadosAnali;
    private String PropostaSolucao;
    
    class AvalMsgPK{
    	private String NrValidac;
        private String RegAnalis;
        
        public AvalMsgPK(String nrVal, String RegAnalis){
        	this.NrValidac = nrVal;
        	this.RegAnalis = RegAnalis;
        }

		public String getNrValidac() {
			return NrValidac;
		}

		public String getRegAnalis() {
			return RegAnalis;
		}

		public void setNrValidac(String nrValidac) {
			NrValidac = nrValidac;
		}

		public void setRegAnalis(String regAnalis) {
			RegAnalis = regAnalis;
		}       
        
    }

    public AvalMsg(String NrValidac, String RegAnalis, String erp, Integer criticidade, String DescrAnalis, String DadosAnali, String PropostaSolucao) {

    	this.mensagemPK = new AvalMsgPK(NrValidac, RegAnalis);
        this.criticidade = criticidade;
        this.erp = erp;
        this.DescrAnalis = DescrAnalis;
        this.DadosAnali = DadosAnali;
        this.PropostaSolucao = PropostaSolucao;
    }

    public AvalMsg(String NrValidac, String RegAnalis, Integer criticidade) {
        this.mensagemPK = new AvalMsgPK(NrValidac, RegAnalis);
        this.criticidade = criticidade;
    }

    
    public String getErp() {
        return erp;
    }

    public void setErp(String erp) {
        this.erp = erp;
    }

    
    public AvalMsgPK getMensagemPK() {
		return mensagemPK;
	}

	public void setMensagemPK(AvalMsgPK mensagemPK) {
		this.mensagemPK = mensagemPK;
	}

	public int getCriticidade() {
            return criticidade;
    }
    public void setCriticidade(int criticidade) {
            this.criticidade = criticidade;
    }
    public String getDescrAnalis() {
            return DescrAnalis;
    }
    public void setDescrAnalis(String descrAnalis) {
            DescrAnalis = descrAnalis;
    }
    public String getDadosAnali() {
            return DadosAnali;
    }
    public void setDadosAnali(String dadosAnali) {
            DadosAnali = dadosAnali;
    }
    public String getPropostaSolucao() {
            return PropostaSolucao;
    }
    public void setPropostaSolucao(String propostaSolucao) {
            PropostaSolucao = propostaSolucao;
    }

    // Validações para criação do registro
    public List<ErrorMessage> validateCreate(boolean cria) {
        List<ErrorMessage> erros = new ArrayList<ErrorMessage>();

        if (cria){
        	if(this.mensagemPK.NrValidac.equals(null) || this.mensagemPK.NrValidac.equals("")){
	            erros.add(new ErrorMessage(
	                    12,
	                    1,
	                    "Número da validação não informado!",
	                    "A informação deve ser diferente de branco."));
	        }
	        
	        if(this.mensagemPK.RegAnalis.equals(null) || this.mensagemPK.RegAnalis.equals("")){
	            erros.add(new ErrorMessage(
	                    13,
	                    1,
	                    "Registro da EFD não informado!",
	                    "A informação deve ser diferente de branco."));
	        }
        }

        if(this.erp.equals(null) || this.erp.equals("")){
            erros.add(new ErrorMessage(
                    1,
                    2,
                    "ERP não informado!",
                    "Informação não obrigatória. Caso possua esta informarção, favor preencher este campo."));
        }

        if(this.DescrAnalis.equals(null) || this.DescrAnalis.equals("")){
            erros.add(new ErrorMessage(
                    1,
                    2,
                    "Descrição da Avaliação não informada!",
                    "Informe uma descrição breve desta avaliação."));
        }

        if(this.DadosAnali.equals(null) || this.DadosAnali.equals("")){
            erros.add(new ErrorMessage(
                    1,
                    2,
                    "Dados da Avalição não informados!",
                    "Informe quais dados serão utilizados para a realização desta avaliação."));
        }

        if(this.DadosAnali.equals(null) || this.DadosAnali.equals("")){
            erros.add(new ErrorMessage(
                    1,
                    2,
                    "Dados da Avalição não informados!",
                    "Informe quais dados serão utilizados para a realização desta avaliação."));
        }

        return erros;        
    }
    
    // Validações para copia do registro
    public List<ErrorMessage> validateCopy() {
        List<ErrorMessage> erros = new ArrayList<ErrorMessage>();

        erros.addAll(validateCreate(true));
        
        return erros;
    }    
    
    // Validações para atualização do registro
    public List<ErrorMessage> validateUpdate() {
        List<ErrorMessage> erros = new ArrayList<ErrorMessage>();

        erros.addAll(validateCreate(false));      
        
        return erros;
    }
    
    // Validações para deleção do registro
    public List<ErrorMessage> validateDelete() {
        List<ErrorMessage> erros = new ArrayList<ErrorMessage>();

        return erros;
    }
}
juceliohv

segue o .hbm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 09/05/2011 16:15:41 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
  <class name="Persistencia.AvalMsg" schema="mtcad" table="avalmsg">
  	
    <composite-id name="AvalMsg" class="Persistencia.AvalMsg">
        <key-property name="mensagemPK.NrValidac" type="java.lang.String" column="NrValidac"/>
        <key-property name="mensagemPK.RegAnalis" type="java.lang.String" column="RegAnalis"/>                
    </composite-id>
    
    <property name="criticidade" type="int">
      <column name="criticidade"/>
    </property>
    <property name="erp" type="java.lang.String">
      <column name="erp"/>
    </property>
    <property name="DescrAnalis" type="java.lang.String">
      <column name="DescrAnalis"/>
    </property>
    <property name="DadosAnali" type="java.lang.String">
      <column name="DadosAnali"/>
    </property>
    <property name="PropostaSolucao" type="java.lang.String">
      <column name="PropostaSolucao"/>
    </property>
  </class>
</hibernate-mapping>
R

Tente definir assim sua chave composta:

<composite-id name="mensagemPK" class="Persistencia.AvalMsgPK">   
  <key-property name="NrValidac" type="java.lang.String" column="NrValidac"/>   
  <key-property name="RegAnalis" type="java.lang.String" column="RegAnalis"/>                   
</composite-id>
juceliohv

Funcionou roger!

Aparecu outro bug.

Quando vou inserir um novo registro faço uma validação para verifica se já não existe um registro com a mesma PK no banco. Porém está dando erro neste algorítimo.

try{ transaction = session.beginTransaction(); List result = session.createCriteria(AvalMsg.class) .add(Restrictions.eq("RegAnalis", mensagem.getMensagemPK().getRegAnalis())) .add(Restrictions.eq("NrValidac", mensagem.getMensagemPK().getNrValidac())).list();

INFO: table found: mtavalpiscofins.avalregistro 11/05/2011 17:49:56 org.hibernate.tool.hbm2ddl.TableMetadata <init> INFO: columns: [flag, cod_reg, des_reg, cod_cnpj, num_seq, datahora, cod_reg_pai] org.hibernate.QueryException: could not resolve property: RegAnalis of: Persistencia.AvalMsg at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:44) at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:38) at org.hibernate.persister.entity.AbstractEntityPersister.getSubclassPropertyTableNumber(AbstractEntityPersister.java:1375) at org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:31) at org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1350) at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:434) at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumnsUsingProjection(CriteriaQueryTranslator.java:394) at org.hibernate.criterion.SimpleExpression.toSqlString(SimpleExpression.java:45) at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:334) at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:82) at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:67) at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1550) at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283) at Persistencia.dao.AvalMsgDAO.createRecord(AvalMsgDAO.java:47)

R

Não uso Criteria, mas meu chute é que vai funcionar assim:

List result = session.createCriteria(AvalMsg.class)  
  .add(Restrictions.eq("mensagemPK.RegAnalis", mensagem.getMensagemPK().getRegAnalis()))  
  .add(Restrictions.eq("mensagemPK.NrValidac", mensagem.getMensagemPK().getNrValidac()))
  .list();
juceliohv

Boa noite Roger. :slight_smile:

Desta forma também não deu certo.

Você comentou que não usa criteria para procurar registros. O que você usa? :idea:

R

Uso HQL:

http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/queryhql.html

Criado 9 de maio de 2011
Ultima resposta 11 de mai. de 2011
Respostas 12
Participantes 4