Hibernate, ajuda com chave primária composta

Olá, comecei a trabalhar a pouco tempo com Hibernate, li este tópico, mas não consegui obter sucesso.

Meu problema é o seguinte, tenho uma view em postgre, ela junta dados de duas tabelas diferentes Clientes e Funcionários, tenho ela mapeada, porém ocorre que um cliente tem um id e um funcionario tem um id também, até ai tudo bem, porém quando juntam-se as duas tabelas pela view os ids ficam repetidos, exemplo:

Funcionario ID Nome 1 José 2 Carlos 3 João

Cliente ID Nome 1 Paulo 2 Ricardo 3 Felipe

View Contato(Funcionario x Cliente) ID Nome Tipo 1 José Funcionário 2 Carlos Funcionário 3 João Funcionário 1 Paulo Cliente 2 Ricardo Cliente 3 Felipe Cliente

Como o Hibernate está considerando o ID como chave primaria ele está pegando o primeiro nº que aparece da chave e ignorando os demais, no caso acima ele pegaria o José, mas não pegaria o Paulo, pois já existe o ID 1, logo teria que usar uma chave composta com o ID e Tipo, porém não sei como.

Não posso alterar a view, então estava tentando usar uma composite-id, porém como os dados vem da mesma tabela estou me atrapalhando um pouco, pois não achei nenhum exemplo com isso.

Obrigado.

O item 5.1.7 do manual do Hibernate fala sobre composite-id:
http://www.hibernate.org/hib_docs/reference/en/html/mapping.html

Vou tentar arrumar um exemplo pra você.

Abraços.

Obrigado, já li essa parte, porém como disse, não consegui, deixei assim:

<class name="Contato" table="viewContato" lazy="false" > <composite-id name="contatoPk" class="ContatoPk"> <key-property name="idContato" column="id_contato" type="java.lang.Integer" /> <key-property name="txtTipoContato" type="java.lang.String" column="txtTipoContato" /> </composite-id> <property.......

Bom…

Segue o exemplo que tenho e que funciona perfeitamente em minha aplicação:

Eu tenho uma view que possui uma chave composta entre o id de um usuário e sua chave.
Ao invés de possuir as propriedades id e chave a classe usuário possui uma classe que possui estas duas propriedades representando minha chave composta.
As classes ficam assim:

  • Usuario.java

[code]package br.com.xxxxx.model;

import java.util.Date;

public class Usuario {

private static final long serialVersionUID = 1L;

private UsuarioPK usuarioPK;

private String email;

private String nome;

public Usuario(){
	this.usuarioPK = new UsuarioPK();
}

//getters and setters

}[/code]

-UsuarioPK.java

[code]package br.com.xxxxx.model;

import java.io.Serializable;

import java.math.BigDecimal;

public class UsuarioPK implements Serializable{

private static final long serialVersionUID = 1L;

private BigDecimal id;

private String chave;

//getters and setters

}[/code]

Dessa forma, o mapeamento da classe Usuario no hibernate deixa de usar o id e passa a usar o composite-id.
Segue exemplo:

  • Usuario.hbm.xml
...
<composite-id name="usuarioPK" class="br.com.xxxxx.model.UsuarioPK">
	<key-property name="id" type="big_decimal">   
		<column name="USUA_ID_USUARIO" sql-type="number(5,0)" />   
	</key-property>   
	<key-property name="chave" type="string" length="4">   
		<column name="USUA_CD_CHAVE" sql-type="char(4)" />   
	</key-property>   
</composite-id>
...

E no mapeamento das classes que fazem referência à classe Usuario:

  • Solicitacao.xml.hbm
...
<many-to-one
			name="usuarioSolicitante"
			class="br.com.xxxxx.model.Usuario"
			cascade="all"
			lazy="false" 
			insert="false" update="false" > 
	<column name="USUA_ID_USUARIO_SOLICITANTE" sql-type="number(5,0)" />
	<column name="USUA_CD_CHAVE_SOLICITANTE" sql-type="char(4)"/>
</many-to-one>
...

Abaixo, a classe que faz referência à classe Usuario:

  • Solicitacao.java

[code]package br.com.xxxxx.model;

//imports

public class Solicitacao implements Comparable {

private static final long serialVersionUID = 1L;

private String id;

private Usuario usuarioSolicitante;

//getters and settings

}[/code]

Enfim…
Isso funcionou muito bem.
Espero que seja útil pra você!

Abraços.

Obrigado mesmo, consegui fazer aqui, obrigado mesmo. :slight_smile:

Que bom que funcionou!

Abraços.

Peço desculppa por me intrometer no post mas estou a tentar construir uma consulta a uma tabela com chave composta e não estou a conseguir, a aplicação devolve o erro:

Missing column: feriasfuncPK in PES.dbo.feriasfunc

onde feriasfuncPK é o objecto da classe que define a chave composta. Parece-me estranho mas acho que o Jboss está a interpreta-lo como um atributo normal ou seja mais uma coluna na tabela.

17:04:46,877 INFO [TableMetadata] columns: [dias_ferias, dias_suplement, dias_por_gozar, dias_antig, numero, obs, data_login, ano, login, dias_descontados, dias_gozados, rowid, dias_acumulados, dias_idade] 17:04:46,877 WARN [ServiceController] Problem starting service persistence.units:ear=fFunc-ear.ear,unitName=fFunc javax.persistence.PersistenceException: [PersistenceUnit: fFunc] Unable to build EntityManagerFactory at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677) ... at java.lang.Thread.run(Unknown Source) Caused by: org.hibernate.HibernateException: Missing column: feriasfuncPK in PES.dbo.feriasfunc at org.hibernate.mapping.Table.validateColumns(Table.java:277) ... at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669) ... 145 more ...

Classe feriasfunc.java

[code]@Entity
public class feriasfunc implements Serializable {

@EmbeddedId
private FeriasfuncPK feriasfuncPK;
private Integer rowid;
private Integer dias_ferias;
private Integer dias_suplement;
private Float dias_descontados;
private Float dias_acumulados;
private Float dias_gozados;
private Float dias_por_gozar;
private String obs;
private String login;
private Date data_login;
private Integer dias_idade;
private Integer dias_antig;



// attribute getters/setters with annotations

public feriasfunc()
{
	this.feriasfuncPK = new FeriasfuncPK();
}

/**
 * @param feriasfuncPK the feriasfuncPK to set
 */
public void setFeriasfuncPK(FeriasfuncPK feriasfuncPK) {
	this.feriasfuncPK = feriasfuncPK;
}

/**
 * @return the feriasfuncPK
 */


public FeriasfuncPK getFeriasfuncPK() {
	return feriasfuncPK;
}


[/code]

classe FeriasfuncPK.java

package org.domain.fFunc.entity;

import java.io.Serializable;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;




public class FeriasfuncPK implements Serializable {
	        
	        //declare composite properties
	        // declare constructor
		
		public Integer numero;
		public Integer ano;
		
		public void setNumero(Integer numero) {
			this.numero = numero;
		}
		
	   
		public Integer getNumero() {
			return numero;
		}
	    
		public void setAno(Integer ano) {
			this.ano = ano;
		}
		
		public  Integer getAno() {
			return ano;
		}

                ....
		[/code]


[b]e por fim o hbm[/b]

[code]<hibernate-mapping package="org.domain.fFunc.entity">
 <class catalog="PES" name="feriasfunc" table="feriasfunc">

   <composite-id
        name="feriasfuncPK"
        class="org.domain.fFunc.FeriasfuncPK">              
        <key-property  name="numero" column="numero" type="integer" />
        <key-property name="ano" column="ano" type="integer" />         
   </composite-id>
...

Se poderem ajudar agradeço bastante.

Tente utilizar feriasfuncPK.ano e feriasfuncPK.numero dentro de suas consultas.

Abraços.