Problema com consulta em Hibernate/criteria

8 respostas
malikoski

Olá pessoal.

Estou com problema em uma consulta com hibernate que não estou conseguindo achar a solução. O banco de dados ja é antigo e por isso tem uma classe PK. Aí vão as classes:

Classe Geral (tabela GERAL)

@Entity
@Table(schema = "CAD", name = "GERAL")
public class Cadastro {
	@Id
	@Column(name = "NUM_CADASTRO")
	@NotEmpty
	private int numero;

        ... 
       
      	@OneToMany(fetch = FetchType.LAZY, mappedBy = "atividadePessoaPK.cadastro")
	private List<AtividadePessoa> atividadePessoa; 
      
       .. // getters e setters

Classe AtividadePessoa (tabela ATIVID_PESSOA)

@Entity(name = "atividadePessoa")
@Table(schema = "CAD", name = "ATIVID_PESSOA")
public class AtividadePessoa {
	@EmbeddedId
	private AtividadePessoaPK atividadePessoaPK;

	@Column(name = "DTA_EXCLUSAO")
	Calendar dataExclusao;

        ..//outros campos - getters e setters

Classe PK - AtividadePessoaPK

@SuppressWarnings("serial")
@Embeddable
public class AtividadePessoaPK implements Serializable {

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "NUM_CADASTRO", referencedColumnName = "NUM_CADASTRO")
	private Cadastro cadastro;

	@ManyToOne(fetch = FetchType.LAZY) //, targetEntity = Atividade.class)
	@JoinColumn(name = "COD_ATIVIDADE", referencedColumnName = "COD_ATIVIDADE"  )
	private AtividadeCadastro atividade;

	@Column(name = "DTA_INICIO_ATV")
	Calendar dataInicioAtividade;

        ... //getters and setters

E finalmente a classe AtividadeCadastro (tabela ATIVIDADES)

@Entity(name = "atividades")
@Table(schema = "CAD", name = "ATIVIDADES")
public class AtividadeCadastro {
	@Id
	@Column(name = "COD_ATIVIDADE")
	private int codigo;

	@Column(name = "DSC_ATIVIDADE")
	private String descricao;

	@Column(name = "IDN_COMISSAO")
	private String comissao;
 
        ... //getters e setters

O que eu quero fazer é a seguinte consulta:

SELECT * FROM CAD.GERAL G
INNER JOIN CAD.ATIVID_PESSOA AP ON AP.NUM_CADASTRO = G.NUM_CADASTRO
INNER JOIN ATIVIDADES A ON A.COD_ATIVIDADE = AP.COD_ATIVIDADE
WHERE A.IDN_COMISSAO = 'V'
WITH UR

Em Hibernate

public List<Cadastro> pegaTodos(int start, int limit) {
		Criteria c = session.createCriteria(Cadastro.class);
		if (limit > 0) {
			c.setFirstResult(start);
			c.setMaxResults(limit);
		}
		if (isFiltroVendedor()) {
			c.createAlias("atividadePessoa", "atividadePessoa");
			c.createAlias("atividadePessoa.atividadePessoaPK.atividade", "atividade");
			c.add(Restrictions.eq("atividade.comissao","V"));
		}
		c.addOrder(Order.asc("id"));
		return (List<Cadastro>) c.list();
	}

Tem uma propriedade filtroVendedor antes de fazer a consulta que seto para true e assim ele passa pelo método isFiltroVendedor. A questão que o hibernate não faz o inner join com a tabela ATIVIDADES , somente com ATIVID_PESSOA que podem ser várias para cada cadastro. E assim ele gera a SQL mas como não faz o inner join com ATIVIDADES ele não encontra o campo “comissao” .

Ja tentei com createCriteria(para cada classe), setFetchMode e nada funcionou. Não sei se é alguma coisa errada nas entidades com os relacionamentos ou alguma coisa que precisa ser feita na consulta do hibernate.

Obrigado desde já.

8 Respostas

drsmachado

Não consegui encontrar a forma que você coloca a tabela ATIVIDADES na criteria…

malikoski

Drsmachado, ela é a classe AtividadeCadastro e está na classe PK AtividadePessoaPK como atividade. Então na criteria eu coloquei:

c.createAlias("atividadePessoa", "atividadePessoa");  
        c.createAlias("atividadePessoa.atividadePessoaPK.atividade", "atividade");  
        c.add(Restrictions.eq("atividade.comissao","V"));

Então, eu referenciei como atividadePessoa.atividadePessoaPK.atividade

malikoski

Ninguém?

drsmachado

Desculpe, não havia entendido a relação.
Veja este artigo, creio que irá ajudar
http://www.roseindia.net/hibernate/examples/criteria/hibernate-criteria-join-api.html

malikoski

Então drsmachado,

Eu tinha lido esse artigo. Essa foi a primeira forma que tentei utilizar no projeto. Não deu certo infelizmente.

malikoski

UP

drsmachado

Esse tipo de coisa não ajuda em nada, até mesmo afasta possíveis foristas que estejam a fim de responder.
Afinal, todos possuem suas atividades, ninguém tem prioridade sobre ninguém aqui.

O caminho do JOIN é aquele, do modo que está tentando nunca vai funcionar.
Faz daquela forma e posta aí se deu erro.

malikoski

Bom meu caro, desculpe. Mas seu comentário sobre isso poderia ter passado por MP.

Vamos lá.

Como te disse tentei de todas formas. Entre elas com o setFetchMode e de vários jeitos. Devo estar usando de uma forma errada. Aí está.

Criteria c = session.createCriteria(Cadastro.class);
	        c.setFetchMode("atividadePessoa", FetchMode.JOIN)
	        .setFetchMode("atividadePessoa.atividadePessoaPK.atividade", FetchMode.JOIN)
               .add(Restrictions.eq("atividadePessoa.atividadePessoaPK.atividade.comissao", "V"));

o Erro:

exception raised, check root cause for details: org.hibernate.QueryException: could not resolve property: atividadePessoa.atividadePessoaPK.atividade.comissao of: br.com.diplomata.dominio.cadastro.Cadastro
...
Criado 16 de abril de 2012
Ultima resposta 19 de abr. de 2012
Respostas 8
Participantes 2