Hql, chave composta, right join

1 resposta
A

Pessoal, estou ha um tempo batendo cabeca aqui e depois de vasculhar muita coisa nao consegui achar uma saida.
Basicamente é a ideia que criar tipos de dados mais complexos para os usuarios do sistema relacionarem como eles quiserem.

Tenho o seguinte cenário:

@Entity
@SequenceGenerator(name = "SEQ_TIPO_DADOS_PESSOA", sequenceName = "SEQ_TIPO_DADOS_PESSOA", allocationSize = 1)
public class TipoDadosPessoa implements Serializable {

	private static final long serialVersionUID = 930238550723053990L;
	@Id
        @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "SEQ_TIPO_DADOS_PESSOA")
	private int cdTipoDadosPessoa;
	private String nmTipoDadosPessoa;
	private String tpDados;
        // get's e set's
}

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@SequenceGenerator(name = "SEQ_PESSOA", sequenceName = "SEQ_PESSOA", allocationSize = 1)
public class Pessoa implements Serializable {

	private static final long serialVersionUID = -43591332807421018L;
	@Id
        @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "SEQ_PESSOA")
	private int cdPessoa;
	private String tpPessoa; // Fisica - Juridica
	private String nmPessoa;
	private String nrCpfCnpj;
        // get's e set's
}

@Entity
@SequenceGenerator(name = "SEQ_DADOS_PESSOA", sequenceName = "SEQ_DADOS_PESSOA", allocationSize = 1)
public class DadosPessoa implements Serializable {

	private static final long serialVersionUID = 3644031969004966534L;
	private String dsDescricao;
	@EmbeddedId 
	private DadosPessoaPK chaveComposta;
        // get's e set's
}

@Embeddable
public class DadosPessoaPK implements Serializable {
	private static final long serialVersionUID = 1L;
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name="cdTipoDadosPessoa")
	private TipoDadosPessoa cdTipoDadosPessoa;
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "cdPessoa")
	private Pessoa cdPessoa;
        // get's e set's
}

A base de dados:

Pessoa
cdPessoa = 1 , nmPessoa = arthur , tpPessoa = F , cpfCnpj = 1234

TipoDadosPessoa

cdTipoDadosPessoa = 1, nmTipoDadosPessoa = CNH , tpDados = Integer
cdTipoDadosPessoa = 2, nmTipoDadosPessoa = Numero de Sobrinhos , tpDados = Integer
cdTipoDadosPessoa = 3, nmTipoDadosPessoa = Numero de Automoveis , tpDados = Integer
cdTipoDadosPessoa = 4, nmTipoDadosPessoa = Aniversario do Avo , tpDados = Date

DadosPessoa
cdPessoa = 1 , cdTipoDadosPessoa = 1 , dsDescricao = 000111222

Preciso trazer todos os TipoDadosPessoa mesmo que nao haja um relacionamento com pessoa.

No mundo relacional seria relativamente simples:

select dp.cdPessoa,tdp.cdTipoDadosPessoa, dp.dsdescricao from dadospessoa dp
left join pessoa p on p.cdPessoa = dp.cdPessoa 
right join tipodadospessoa tdp on tdp.cdTipoDadosPessoa = dp.cdTipoDadosPessoa
where dp.cdPessoa = 1 or dp.cdPessoa is null

O resultado do SQL seria:
DadosPessoa
cdPessoa = 1 , cdTipoDadosPessoa = 1 , dsDescricao = 000111222
cdPessoa = null , cdTipoDadosPessoa = 2 , dsDescricao = null
cdPessoa = null , cdTipoDadosPessoa = 3 , dsDescricao = null
cdPessoa = null , cdTipoDadosPessoa = 4 , dsDescricao = null

Porem, ao montar o hql nao estou sabendo manipular a chave composta embarcada, usando o hibernate tools eu consigo notar alguns comportamentos que me chamam a atencao

O HQL:

select dp from DadosPessoa dp
right join dp.chaveComposta.cdTipoDadosPessoa t
left join dp.chaveComposta.cdPessoa p
where p.cdPessoa = 1 or p is null

Desta forma ele me traz 3 objetos, sendo 3 deles null ( provavelmente pelo produto cartesiano que deu ) e um certinho ( unico relacionado )

Na minha cabeca, a forma que eu estava pensando o hibernate montaria “metade” do objeto pra mim, traria 4 objetos DadosPessoa, porem 3 deles sem o relacionamento de pessoa. nao sei se fui claro.
Vamos a um exemplo de como eu imaginava ( e gostaria que voltasse assim )

DadosPessoa
chaveComposta.cdPessoa.cdPessoa = 1 , chaveComposta.cdTipoDadosPessoa.cdTipoDadosPessoa = 1 , dsDescricao = 000111222
chaveComposta.cdPessoa = null , chaveComposta.cdTipoDadosPessoa.cdTipoDadosPessoa = 2
chaveComposta.cdPessoa = null , chaveComposta.cdTipoDadosPessoa.cdTipoDadosPessoa = 3
chaveComposta.cdPessoa = null , chaveComposta.cdTipoDadosPessoa.cdTipoDadosPessoa = 4

O HQL executa, porem quando vou varrer a lista de retorno, ele da uma excessao de nullpointer obviamente por acessar metodos de um objeto nulo.

Como o desespero eh grande, a velha tatica de brutal force entrou em acao.
como por exemplo

select new DadosPessoa(  new DadosPessoaPK( p , tp  ) )  from DadosPessoa dp 
  right join dp.chaveComposta.cdTipoDadosPessoa tp
  left join dp.chaveComposta.cdPessoa p
  where p.cdPessoa = 1

Mas esse ae nem compila…
Uma outra tentativa, porem esta gera uns joins muito doidos com entidades que eu nao explicitei no hql, por exemplo

select p , tp    from DadosPessoa dp 
  right join dp.chaveComposta.cdTipoDadosPessoa tp
  left join dp.chaveComposta.cdPessoa p

Nao sei se fui claro… mas realmente nao faco a minima ideia de como resolver isso… alguem se habilita??

Grato desde já!

1 Resposta

A

agora que me toquei, postei no local errado…
se puderem migrar para a categoria de persistencia eu agradeceria.

Criado 23 de dezembro de 2009
Ultima resposta 23 de dez. de 2009
Respostas 1
Participantes 1