GUJ
Notícias, artigos e o maior fórum brasileiro sobre Java
home
fórum
notícias
tópicos recentes
empregos
artigos
Bem-vindo ao GUJ.
Crie seu login
, ou digite-o para logar no site.
Usuário:
Senha:
Subquery com join entre dois ou mais campos - Criteria
Índice dos Fóruns
»
Persistência: Hibernate, JPA, JDBC e outros
Autor
Mensagem
27/01/2009 15:28:38
Assunto:
Subquery com join entre dois ou mais campos - Criteria
braudes
HelloWorld
Membro desde: 22/10/2007 12:49:43
Mensagens: 13
Localização: Goiânia - Goiás
Offline
Pessoal,
Primeiramente, seguem abaixo classe e tabela:
CLASSE:
@Entity @Table(name="fin_LancamentosDespesas") public class LancamentoDespesa extends MappedEntity{ private static final long serialVersionUID = 2114159600713444333L; private Integer numeroLancamento; private Date dataCompetencia; private Date dataEmissao; private String observacao; private String numeroDocumento; private Date dataOperacao; private UsuarioSIG responsavelOperacao; private Boolean flagCaixa; private Double valorBruto; private Double valorLiquido; private UsuarioSIG responsavelConferencia; private Fornecedor fornecedor; private TipoDocumento tipoDocumento; private Date dataConferencia; private Empresa empresa; private TipoOrigem tipoOrigem; private Date dataCancelamento; private List<ParcelaLancamentoDespesa> listaParcela; private List<RateioLancamento> listaRateio; private List<RetencaoLancamentoDespesa> listaRetencao; @Id @Override @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "NUMG_LancamentoDespesa") public Long getId() { return super.getId(); } @Column(name="NUMR_LancamentoDespesa") public Integer getNumeroLancamento() { return numeroLancamento; } public void setNumeroLancamento(Integer numeroLancamento) { this.numeroLancamento = numeroLancamento; } @Column(name="DATA_Cancelamento") @Temporal(TemporalType.TIMESTAMP) public Date getDataCancelamento() { return dataCancelamento; } public void setDataCancelamento(Date dataCancelamento) { this.dataCancelamento = dataCancelamento; } @Column(name = "DATA_Competencia") @NotNull(message = "A data competência do lançamento deve ser preenchida.") public Date getDataCompetencia() { return dataCompetencia; } public void setDataCompetencia(Date dataCompetencia) { this.dataCompetencia = dataCompetencia; } @Column(name = "DATA_Emissao") @NotNull(message = "A data emissão do lançamento deve ser preenchida.") @Temporal(TemporalType.DATE) public Date getDataEmissao() { return dataEmissao; } public void setDataEmissao(Date dataEmissao) { this.dataEmissao = dataEmissao; } @Column(name = "DESC_Observacao") public String getObservacao() { return observacao; } public void setObservacao(String observacao) { this.observacao = observacao; } @Column(name = "CODG_Documento") @NotNull(message = "O numero documeto do lançamento deve ser preenchido.") public String getNumeroDocumento() { return numeroDocumento; } public void setNumeroDocumento(String numeroDocumento) { this.numeroDocumento = numeroDocumento; } @Column(name = "DATA_Operacao") @NotNull(message = "A data de operação do lançamento deve ser preenchida.") public Date getDataOperacao() { return dataOperacao; } public void setDataOperacao(Date dataOperacao) { this.dataOperacao = dataOperacao; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "NUMG_UsuarioOperacao") @NotNull(message = "O responsável operação do lançamento deve ser preenchido.") public UsuarioSIG getResponsavelOperacao() { return responsavelOperacao; } public void setResponsavelOperacao(UsuarioSIG responsavelOperacao) { this.responsavelOperacao = responsavelOperacao; } @Column(name = "FLAG_Caixa") @NotNull(message = "O flag caixa do lançamento deve ser preenchido.") public Boolean getFlagCaixa() { return flagCaixa; } public void setFlagCaixa(Boolean flagCaixa) { this.flagCaixa = flagCaixa; } @Column(name = "VALR_Bruto") @NotNull(message = "O valor bruto do lançamento deve ser preenchido.") public Double getValorBruto() { return valorBruto; } public void setValorBruto(Double valorBruto) { this.valorBruto = valorBruto; } @Column(name = "VALR_Liquido") @NotNull(message = "O valor líquido do lançamento deve ser preenchido.") public Double getValorLiquido() { return valorLiquido; } public void setValorLiquido(Double valorLiquido) { this.valorLiquido = valorLiquido; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "NUMG_UsuarioConferencia") public UsuarioSIG getResponsavelConferencia() { return responsavelConferencia; } public void setResponsavelConferencia(UsuarioSIG responsavelConferencia) { this.responsavelConferencia = responsavelConferencia; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "NUMG_Fornecedor") @NotNull(message = "O fornecedor do lançamento deve ser preenchido.") public Fornecedor getFornecedor() { return fornecedor; } public void setFornecedor(Fornecedor fornecedor) { this.fornecedor = fornecedor; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "NUMG_DocumentoTipo") @NotNull(message = "O tipo documento do lançamento deve ser preenchido.") public TipoDocumento getTipoDocumento() { return tipoDocumento; } public void setTipoDocumento(TipoDocumento tipoDocumento) { this.tipoDocumento = tipoDocumento; } @Column(name = "DATA_Conferencia") @Temporal(TemporalType.TIMESTAMP) public Date getDataConferencia() { return dataConferencia; } public void setDataConferencia(Date dataConferencia) { this.dataConferencia = dataConferencia; } @OneToMany(mappedBy = "lancamentoDespesa", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }) @Cascade( { org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) public List<ParcelaLancamentoDespesa> getListaParcela() { if (listaParcela == null){ listaParcela = new ArrayList<ParcelaLancamentoDespesa>(); } return listaParcela; } public void setListaParcela(List<ParcelaLancamentoDespesa> listaParcela) { this.listaParcela = listaParcela; } @OneToMany(mappedBy = "lancamentoDespesa", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }) @Cascade( { org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) public List<RateioLancamento> getListaRateio() { if (listaRateio == null){ listaRateio = new ArrayList<RateioLancamento>(); } return listaRateio; } public void setListaRateio(List<RateioLancamento> listaRateio) { this.listaRateio = listaRateio; } @OneToMany(mappedBy = "lancamentoDespesa", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }) @Cascade( { org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) public List<RetencaoLancamentoDespesa> getListaRetencao() { if (listaRetencao == null){ listaRetencao = new ArrayList<RetencaoLancamentoDespesa>(); } return listaRetencao; } public void setListaRetencao(List<RetencaoLancamentoDespesa> listaRetencao) { this.listaRetencao = listaRetencao; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "NUMG_Empresa") @NotNull(message = "A empresa do lançamento deve ser preenchida.") public Empresa getEmpresa() { return empresa; } public void setEmpresa(Empresa empresa) { this.empresa = empresa; } @Column(name = "TIPO_Origem") @Type(type = "org.hibernate.usertype.TipoOrigemUserType") @NotNull(message = "A origem do Lancamento Deve se informada.") public TipoOrigem getTipoOrigem() { return tipoOrigem; } public void setTipoOrigem(TipoOrigem tipoOrigem) { this.tipoOrigem = tipoOrigem; } }
TABELA
Column_name Type NUMG_LancamentoDespesa int NUMR_Versao smallint DATA_Competencia smalldatetime DATA_Emissao datetime DESC_Observacao varchar CODG_Documento varchar DATA_Operacao datetime NUMG_UsuarioOperacao int FLAG_Caixa bit VALR_Bruto money VALR_Liquido money NUMG_UsuarioConferencia int DATA_Conferencia datetime NUMG_Fornecedor int NUMG_DocumentoTipo tinyint NUMG_Empresa smallint TIPO_Origem tinyint NUMR_LancamentoDespesa int DATA_Cancelamento datetime
Estou procurando exemplos de criteria utilizando subquery mas só achei exemplos onde o join é somente com uma coluna, tipo (código 1):
SELECT ld.* FROM dbo.fin_LancamentosDespesas ld INNER JOIN ( SELECT MAX(DATA_Operacao) AS DATA_Operacao FROM dbo.fin_LancamentosDespesas WHERE NUMG_Empresa = 70 AND CODG_Documento = '210109-002' AND DATA_Emissao = '2009-01-21 00:00:00.000' AND NUMG_Fornecedor = 58 AND NUMG_DocumentoTipo = 5 AND DATA_Cancelamento = '1900-01-01 00:00:00.000' GROUP BY NUMR_LancamentoDespesa) ldt ON ld.DATA_Operacao = ldt.DATA_Operacao
O que estou precisando é de um join entre dois campos (código 2):
SELECT ld.* FROM dbo.fin_LancamentosDespesas ld INNER JOIN ( SELECT MAX(DATA_Operacao) AS DATA_Operacao, NUMR_LancamentoDespesa FROM dbo.fin_LancamentosDespesas WHERE NUMG_Empresa = 70 AND CODG_Documento = '210109-002' AND DATA_Emissao = '2009-01-21 00:00:00.000' AND NUMG_Fornecedor = 58 AND NUMG_DocumentoTipo = 5 AND DATA_Cancelamento = '1900-01-01 00:00:00.000' GROUP BY NUMR_LancamentoDespesa) ldt ON ld.NUMR_LancamentoDespesa = ldt.NUMR_LancamentoDespesa AND ld.DATA_Operacao = ldt.DATA_Operacao
O máximo que consegui chegar com criteria foi (código 3):
select this_.* from dbo.fin_LancamentosDespesas this_ where exists ( select max(this0__.DATA_Operacao) as y0_, this0__.NUMR_LancamentoDespesa as y1_ from dbo.fin_LancamentosDespesas this0__ where this_.CODG_Documento='210109-002' and this_.DATA_Emissao='2009-01-21 00:00:00.000' and this_.NUMG_Fornecedor=58 and this_.NUMG_Empresa=70 and this_.NUMG_DocumentoTipo = 5 and this_.DATA_Cancelamento='1900-01-01 00:00:00.000' and this0__.DATA_Operacao=this_.DATA_Operacao and this0__.NUMR_LancamentoDespesa=this_.NUMR_LancamentoDespesa group by this0__.NUMR_LancamentoDespesa )
E o código da criteria utilizado foi (código 4):
DetachedCriteria dc = DetachedCriteria.forClass(LancamentoDespesa.class,"ld"); dc.setProjection( Projections.projectionList() .add(Projections.max("ld.dataOperacao")) .add(Projections.groupProperty("ld.numeroLancamento")) ); dc.add(Restrictions.eq("ld.numeroDocumento", numeroDocumento)); dc.add(Restrictions.eq("ld.dataEmissao", dataEmissao)); dc.add(Restrictions.eq("ld.fornecedor", fornecedor)); dc.add(Restrictions.eq("ld.empresa", empresa)); dc.add(TSQLFunctions.is1900("ld.dataCancelamento")); dc.add(Property.forName("ld.dataOperacao").eqProperty("ld1.dataOperacao")); dc.add(Property.forName("ld.numeroDocumento").eqProperty("ld1.numeroDocumento")); Criteria c = session.createCriteria(LancamentoDespesa.class,"ld1") .add(Subqueries.exists(dc));
Gostaria de saber se há uma forma de conseguir gerar o SQL do código 2.
Obrigado.
Índice dos Fóruns
»
Persistência: Hibernate, JPA, JDBC e outros
Ir para:
Selecione um Fórum
Notícias
Assuntos gerais (Off-topic)
MundoJ - Artigos, Notícias e Debates
Artigos e Tutoriais
Java Básico
Java Avançado
Ferramentas, Frameworks e Utilitários
Desenvolvimento Web
Interface Gráfica
Google Android e Java Micro Edition (ME)
Certificação Java
Persistência: Hibernate, JPA, JDBC e outros
Java Enterprise Edition (Java EE)
Frameworks e Bibliotecas brasileiros
RIA - Flex, JavaFX e outros
Arquitetura de Sistemas
Metodologias de Desenvolvimento e Testes de Software
JavaScript
Ruby & Ruby on Rails
Outras Linguagens
Powered by
JForum 2.1.8
©
JForum Team