Hibernate Criteria + OneToMany

10 respostas
V

Olá,

Tenho esse relacionamento:

Departamento.java

public class Departamento
{
	private Long id;
	private String nome;
	private Date dataCriacao;
	private Date dataAlteracao;
	
	private List<Recurso> cargos;

	@OneToMany(targetEntity=Cargo.class, mappedBy="departamento", fetch=FetchType.EAGER)
	@JoinColumn(name="fk_depId")
	public List<Recurso> getCargos()
	{
		return cargos;
	}

	public void setCargos(List<Recurso> cargos)
	{
		this.cargos = cargos;
	}
}

Cargo.java

public class Cargo implements Recurso
{
	private Long id;
	private String nome;
	private double valorHora;
	private Date dataCriacao;
	private Date dataAlteracao;
	
	private Empresa empresa;
	private Fornecedor fornecedor;
	private Departamento departamento;
	private List<Funcionario> funcionarios;

	@ManyToOne(targetEntity=Departamento.class)
	@JoinColumn(name="fk_depId")
	@ForeignKey(name="dep_id")
	public Departamento getDepartamento()
	{
		return departamento;
	}
	public void setDepartamento(Departamento departamento)
	{
		this.departamento = departamento;
	}
}

Fornecedor.java

public class Fornecedor
{
	private Long id;
	private String apelido;
	private String razaoSocial;
	private Date dataCriacao;
	private Date dataAlteracao;
	
	private List<Cargo> cargos;

	@OneToMany(mappedBy="fornecedor", targetEntity=Cargo.class, fetch=FetchType.EAGER)
	public List<Cargo> getCargos()
	{
		return cargos;
	}
	public void setCargos(List<Cargo> cargos)
	{
		this.cargos = cargos;
	}
}

*obs.: coloquei apenas os relacionamentos necessários para a pergunta

Departamento 1 : N Cargo
Cargo 1 : 1 Fornecedor
Cargo 1 : 1 Empresa

Ou seja, o Cargo pertence a Fornecedor OU a Empresa.

Estou tentando atualmente esta query para fazer a consulta de todos os departamentos onde o FORNECEDOR do cargo seja NULL:

@SuppressWarnings("unchecked")
public List<Departamento> listarPorCargoInterno()
{
	Criteria crit = getSession().createCriteria(getPersistentClass());
	crit.add(Restrictions.isNull("cargos")).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
	return (List<Departamento>) crit.list();
}

Já tentei outras maneiras tb, mas não consigo fazer esse filtro. Como devo fazer?

abs

10 Respostas

V

Galera, alguém consegue dar uma luz?

Em SQL seria algo como:

abs.

A

Já tentou criando um alias para “cargos” para ve se resolve.

V

Já sim. Mas não da certo, pois eu tenho uma lista de cargos, e não um só para criar um alias. Não sei como fazer nessa situação =[

V

Ninguém nunca teve uma situacao parecida? A meu ver, é uma relação e um tipo de filtro bem comum.

Tenho uma lista da EntidadeA na EntidadeB e gostaria de filtrar apenas as EntidadeA que tivessem o status = 1, por exemplo. É exatamente o que estou passando, mas minha inexperiência com Hibernate me faz travar nuns problemas bem básicões =\

A

rapaz se não esta conseguindo, utilize HQL ou o metodo SQL Restrictions do DetacheCriteria e passe o SQL da consulta se esta tendo tanta dificuldade com criteria, eu particularmente já utilizei o alias para coleções e funcionou, mas nunca no caso de testar de uma entidade toda é null, mas para esse caso aqui:

um alias normalmente sempre resolve, mande exibir o SQL na consulta se esta dando erro poste a exceção aqui para poder facilitar e até mesmo os códigos, caso sejam diferentes dos que esta no inicio do post.

Esta usando o hibernate com annotations?

V

Sim, estou usando annotations. Segue meu codigo atual:

public List<Departamento> listarPorCargoInterno()
{
	Criteria crit = getSession().createCriteria(getPersistentClass());
	crit.createAlias("cargos", "c");
	crit.add(Restrictions.isNull("c.fornecedor")).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
	return (List<Departamento>) crit.list();
}

Resultado:

TECNOLOGIA
Programador PHP >> 10 >> sigo.model.Empresa@1ee2c2c
Programador ActionScript >> 15 >> sigo.model.Empresa@1ee2c2c
Programador PHP >> 28 >> null
Programador PHP >> 29 >> null
Programador PHP >> 30 >> null
Programador ActionScript >> 31 >> null
Programador ActionScript >> 32 >> null
Programador ActionScript >> 33 >> null
Programador .NET >> 34 >> null
Programador .NET >> 35 >> null
Programador .NET >> 36 >> null
PLANEJAMENTO
Planejador >> 11 >> sigo.model.Empresa@1ee2c2c
PROJETOS
Gerente de Projetos >> 13 >> sigo.model.Empresa@1ee2c2c
Gerente de Projetos >> 37 >> null
Gerente de Projetos >> 38 >> null
Gerente de Projetos >> 39 >> null
ATENDIMENTO
Atendimento >> 12 >> sigo.model.Empresa@1ee2c2c

Ele deveria ter excluído da consulta todos esses nulls

SQL gerado

00:50:07,414 DEBUG SQL:111 - select cargos0_.fk_depId as fk6_3_, cargos0_.cargo_id as cargo1_3_, cargos0_.cargo_id as cargo1_8_2_, cargos0_.cargo_dataAlteracao as cargo2_8_2_, cargos0_.cargo_dataCriacao as cargo3_8_2_, cargos0_.fk_depId as fk6_8_2_, cargos0_.fk_empId as fk7_8_2_, cargos0_.fk_fornecedorId as fk8_8_2_, cargos0_.cargo_nome as cargo4_8_2_, cargos0_.cargo_valorHora as cargo5_8_2_, empresa1_.emp_id as emp1_9_0_, empresa1_.emp_apelido as emp2_9_0_, empresa1_.emp_dataAlteracao as emp3_9_0_, empresa1_.emp_dataCriacao as emp4_9_0_, empresa1_.emp_nome as emp5_9_0_, empresa1_.emp_overhead as emp6_9_0_, empresa1_.emp_profit as emp7_9_0_, fornecedor2_.for_id as for1_11_1_, fornecedor2_.for_apelido as for2_11_1_, fornecedor2_.for_dataAlteracao as for3_11_1_, fornecedor2_.for_dataCriacao as for4_11_1_, fornecedor2_.for_razaoSocial as for5_11_1_ from cargo cargos0_ left outer join empresa empresa1_ on cargos0_.fk_empId=empresa1_.emp_id left outer join fornecedor fornecedor2_ on cargos0_.fk_fornecedorId=fornecedor2_.for_id where cargos0_.fk_depId=?

Hibernate: select cargos0_.fk_depId as fk6_3_, cargos0_.cargo_id as cargo1_3_, cargos0_.cargo_id as cargo1_8_2_, cargos0_.cargo_dataAlteracao as cargo2_8_2_, cargos0_.cargo_dataCriacao as cargo3_8_2_, cargos0_.fk_depId as fk6_8_2_, cargos0_.fk_empId as fk7_8_2_, cargos0_.fk_fornecedorId as fk8_8_2_, cargos0_.cargo_nome as cargo4_8_2_, cargos0_.cargo_valorHora as cargo5_8_2_, empresa1_.emp_id as emp1_9_0_, empresa1_.emp_apelido as emp2_9_0_, empresa1_.emp_dataAlteracao as emp3_9_0_, empresa1_.emp_dataCriacao as emp4_9_0_, empresa1_.emp_nome as emp5_9_0_, empresa1_.emp_overhead as emp6_9_0_, empresa1_.emp_profit as emp7_9_0_, fornecedor2_.for_id as for1_11_1_, fornecedor2_.for_apelido as for2_11_1_, fornecedor2_.for_dataAlteracao as for3_11_1_, fornecedor2_.for_dataCriacao as for4_11_1_, fornecedor2_.for_razaoSocial as for5_11_1_ from cargo cargos0_ left outer join empresa empresa1_ on cargos0_.fk_empId=empresa1_.emp_id left outer join fornecedor fornecedor2_ on cargos0_.fk_fornecedorId=fornecedor2_.for_id where cargos0_.fk_depId=?

Obrigado.

abs,
André Vendramini

A

Rapaz pelo que entendi da consulta tu quer todos em que fornecedor for null correto?

Esse null dessa linha significa o que? a Empresa? estou achando é que esta faltando coisas nessa sua criteria.

V

É a empresa sim… tanto é que alguns retornam: sigo.model.Empresa@1ee2c2c que são os cargos que pertencem a uma empresa. Segue o trace agora exibindo os fornecedores do Cargo:

CRIAÇAO
Redator >> 8 >> sigo.model.Empresa@1963b3e >> null
Redator >> 9 >> sigo.model.Empresa@2db19d >> null
Diretor de Arte >> 14 >> sigo.model.Empresa@2db19d >> null
Redator >> 16 >> null >> sigo.model.Fornecedor@c3014
Redator >> 17 >> null >> sigo.model.Fornecedor@16dfa45
Redator >> 18 >> null >> sigo.model.Fornecedor@15718f2
Diretor de Arte >> 19 >> null >> sigo.model.Fornecedor@15718f2
Diretor de Arte >> 20 >> null >> sigo.model.Fornecedor@16dfa45
Diretor de Arte >> 21 >> null >> sigo.model.Fornecedor@c3014
Assistente de Arte >> 22 >> null >> sigo.model.Fornecedor@c3014
Assistente de Arte >> 23 >> null >> sigo.model.Fornecedor@16dfa45
Assistente de Arte >> 24 >> null >> sigo.model.Fornecedor@15718f2
Diretor de Criação >> 25 >> null >> sigo.model.Fornecedor@15718f2
Diretor de Criação >> 26 >> null >> sigo.model.Fornecedor@16dfa45
Diretor de Criação >> 27 >> null >> sigo.model.Fornecedor@c3014
TECNOLOGIA
Programador PHP >> 10 >> sigo.model.Empresa@1963b3e >> null
Programador ActionScript >> 15 >> sigo.model.Empresa@1963b3e >> null
Programador PHP >> 28 >> null >> sigo.model.Fornecedor@c3014
Programador PHP >> 29 >> null >> sigo.model.Fornecedor@16dfa45
Programador PHP >> 30 >> null >> sigo.model.Fornecedor@15718f2
Programador ActionScript >> 31 >> null >> sigo.model.Fornecedor@15718f2
Programador ActionScript >> 32 >> null >> sigo.model.Fornecedor@16dfa45
Programador ActionScript >> 33 >> null >> sigo.model.Fornecedor@c3014
Programador .NET >> 34 >> null >> sigo.model.Fornecedor@c3014
Programador .NET >> 35 >> null >> sigo.model.Fornecedor@16dfa45
Programador .NET >> 36 >> null >> sigo.model.Fornecedor@15718f2
PLANEJAMENTO
Planejador >> 11 >> sigo.model.Empresa@1963b3e >> null
PROJETOS
Gerente de Projetos >> 13 >> sigo.model.Empresa@1963b3e >> null
Gerente de Projetos >> 37 >> null >> sigo.model.Fornecedor@15718f2
Gerente de Projetos >> 38 >> null >> sigo.model.Fornecedor@16dfa45
Gerente de Projetos >> 39 >> null >> sigo.model.Fornecedor@c3014
ATENDIMENTO
Atendimento >> 12 >> sigo.model.Empresa@1963b3e >> null

Se existe Empresa, Fornecedor é null. Se existe Fornecedor, Empresa é null.

No meu Criteria, estou criando um alias de uma lista de Cargo e digo que Restrictions.isNull(“c.fornecedor”) (onde “c” é o alias para a lista de Cargo)
Está certo isso? Bom, não, pois não funciona como deveria, rsrs…

Obrigado,

André Vendramini

V

Alguém consegue dar uma ajuda nesse problema? Nesse meu último post está bem exemplificado o que está acontecendo e o que estou tentando fazer… é simples, não? Procurei posts relacionandos aqui e em outros fóruns mas nada… inclusive tem um cara aqui com a mesma dúvida que eu mas sem respostas: https://forum.hibernate.org/viewtopic.php?f=1&t=1002167&view=previous

V

Olá, André, acredito que a essa altura você já deve ter encontrado outra saída, mas passei pelo mesmo problema e encontrei a seguinte solução:

Criteria crit = getSession().createCriteria(getPersistentClass());
crit.createCriteria("cargos").add(Restrictions.isNull("fornecedor"));
return (List<Departamento>) crit.list();

Fica ae para o caso de alguém passar pelo problema.

Abç!

Victor Bonafé

Criado 28 de março de 2010
Ultima resposta 3 de out. de 2011
Respostas 10
Participantes 3