Ajuda com Hibernate Criteria

Salve javeiros…

Coloco um trexo abaixo que para mim parece estar correto, mas estou recebendo uma
exception que não tinha visto até então:

Exception que ocorre na lina do return:
org.springframework.orm.hibernate3.HibernateSystemException: Unknown entity: null; nested exception is org.hibernate.MappingException: Unknown entity: null

O método com problema:

	@Override
	public List<Agendamento> list(final Date inicio, final Date fim, final boolean abertos, boolean pagos) {
		DetachedCriteria c = DetachedCriteria.forClass(Agendamento.class, "ag")
			.addOrder(Order.asc("vencimento"))
			.addOrder(Order.asc("data"))
			.add(Restrictions.ge("vencimento", inicio))
			.add(Restrictions.le("vencimento", fim));
		
		if (!abertos || !pagos) {
			DetachedCriteria dc = DetachedCriteria.forClass(Baixa.class, "bx")
					.setProjection(Projections.sum("valor"))
					.add(Property.forName("agendamento").eqProperty("ag"));
			
			if (!pagos)
				c.add(Property.forName("valor").lt(dc));
			
			if (!abertos)
				c.add(Property.forName("valor").ge(dc));
		}
		
		return template.findByCriteria(c);
	}

acho que as primeiras perguntas a ser respondidas para ver o que houver são:

  • Quais valores estão sendo enviado para o método quando o erro ocorre ? acho que principalmente interessa saber os valores de “pagos” e “abertos” para descobrir se entra na condição
  • Como é, e qual é o mapeamento de Agendamento e Baixa…
  • As 2 classes estão adcionadas a configuração de mapeamento da factory ?
  • o erro é pq algo esta nulo, no meio disso tudo…
  • como é o objeto template ? o que faz o método findByCriteria?

enfim, fica ai as duvidas q podem ajudar a elucidar o problema

Acho que na pressa fui muito superficial…

Vamos as questões (em ordem inversa):

  • o objet template é um HibernateTemplate do Spring (não acho que esteja com problemas);
  • o erro é pq algo está nulo, mas não é um parâmetro nulo para o hibernate, pq retornaria uma NPE;
  • sim, as duas classes estão adicionadas no hibernate.cfg;
  • o mapeamento é um many-to-one em Baixa referenciando Agendamento, e um set(one-to-many) em Agendamento referenciando Baixa;
  • o erro só ocorre quando entra no IF (já considerei todos estes testes).

Em Baixa:

		<many-to-one name="agendamento" column="agendamento_id"/>

Em Agendamento:

<set name="baixas" lazy="false" cascade="all-delete-orphan" inverse="false"> <key column="agendamento_id" /> <one-to-many class="Baixa" /> </set>

Acho que é isso, estou quebrando a cabeça aqui mas realmente nada me ocorreu ainda.
Se alguém puder ajudar fico muito grato.

Resolvi o problema usando HQL (eu prefiro Criteria, mas…).

Talvez ajude alguém com subqueries:

		StringBuffer hql = new StringBuffer("from Agendamento as ag \n" +
				"where (vencimento between ? and ?) \n");
		
		if (!abertos || !pagos) {
			if (!pagos)
				hql.append("and (valor > (select coalesce(sum(valor), 0) from Baixa where agendamento = ag)) \n");
			
			if (!abertos)
				hql.append("and (valor <= (select coalesce(sum(valor), 0) from Baixa where agendamento = ag)) \n");			
		}
		
		hql.append("order by vencimento, data");
		
		return template.find(hql.toString(), new Object[]{inicio, fim});

Evite StringBuffer, prefira StringBuilder, ele é + rapido…

mas ainda acho que o problema no seu criterio é aqui

linha 9 a 12

if (!abertos || !pagos) { DetachedCriteria dc = DetachedCriteria.forClass(Baixa.class, "bx") .setProjection(Projections.sum("valor")) .add(Property.forName("agendamento").eqProperty("ag"));

onde vc diz, que agendamento é igual a uma propriedade “ag” que pertencen ao outro DatachedCriteria, ou seja, ele nao sabe que propriedade é essa…

mas enfim, é complicado sem saber bem como é suas classes… abraço