Como criar uma consulta com inner join
Boa noite. Tenho um menu de opções e dentre estas opções eu chamo o link listarQuartosAlugados
Nele eu acesso o managedBean QuartoBean que me retorna atraves da dao QuartoDAOImpl os quartos indisponiveis. Em uma lista de quartos alugados
Ao clicar em um dos links acesso a classe chamada QuartosAlugados e um managedBean QuartosAlugadosBean nele o seguinte metodo:
public String consultarQuartosAlugados() throws DAOException {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest req = (HttpServletRequest) context.getExternalContext().getRequest();
Quarto q = (Quarto) req.getAttribute("q");
quarto.setId(q.getId());
//fazendo uma consulta ao banco de dados para trazer as informações do quarto alugado
quarto = quartosAlugadosDAO.consultaInformacoesQuartoAlugado(quarto);
return "formAlugaQuarto";
}
nele chamo o metodo de minha QuartosAlugadosDAOImpl chamado consultaInformacoesQuartoAlugado(quarto);
Neste método quero fazer um inner join e trazer os dados sobre a locação do quarto como, o id do hospede, e outras informações para preencher as seguintes telas: tl_consultarQuartosAlugadosI e II. Envio um rascunho destas telas e imagem.
Segue codigo do metodo da DAO:
public Quarto consultaInformacoesQuartoAlugado(Quarto quarto) throws DAOException{
Session session = HibernateUtil.getSession();
try {
// List teste = session.createCriteria(QuartosAlugados.class)
// .add( Restrictions.like("quarto", quarto) )
//
// .list();
Criteria busca =
session.createCriteria("FROM QuartosAlugados al "
+ "inner join Quarto quarto "
+ "where quarto.id = "+quarto.getId());
// busca.add(Expression.eq("id_hospede", id));
return (Quarto) busca;
} catch (org.hibernate.ObjectNotFoundException e) {
return null;
} catch(Exception ex){
throw new DAOException(ex);
}finally{
}
}
Ao executar o metodo ele me retorna o seguinte stackTrace: como posso corrigir este problema
http://paste-it.net/public/o55dd4e/
segue codigos fontes:
principal.jsp : http://paste-it.net/public/u1b331b/
listarQuartosAlugados.jsp: http://paste-it.net/public/xd5c29c/
QuartosAlugadosBean: http://paste-it.net/public/k3f23fc/
QuartosAlugadosDAOImpl: http://paste-it.net/public/c3cfb0c/
Nele eu acesso o managedBean QuartoBean que me retorna atraves da dao QuartoDAOImpl os quartos indisponiveis. Em uma lista de quartos alugados
Ao clicar em um dos links acesso a classe chamada QuartosAlugados e um managedBean QuartosAlugadosBean nele o seguinte metodo:
public String consultarQuartosAlugados() throws DAOException {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest req = (HttpServletRequest) context.getExternalContext().getRequest();
Quarto q = (Quarto) req.getAttribute("q");
quarto.setId(q.getId());
//fazendo uma consulta ao banco de dados para trazer as informações do quarto alugado
quarto = quartosAlugadosDAO.consultaInformacoesQuartoAlugado(quarto);
return "formAlugaQuarto";
}
nele chamo o metodo de minha QuartosAlugadosDAOImpl chamado consultaInformacoesQuartoAlugado(quarto);
Neste método quero fazer um inner join e trazer os dados sobre a locação do quarto como, o id do hospede, e outras informações para preencher as seguintes telas: tl_consultarQuartosAlugadosI e II. Envio um rascunho destas telas e imagem.
Segue codigo do metodo da DAO:
public Quarto consultaInformacoesQuartoAlugado(Quarto quarto) throws DAOException{
Session session = HibernateUtil.getSession();
try {
// List teste = session.createCriteria(QuartosAlugados.class)
// .add( Restrictions.like("quarto", quarto) )
//
// .list();
Criteria busca =
session.createCriteria("FROM QuartosAlugados al "
+ "inner join Quarto quarto "
+ "where quarto.id = "+quarto.getId());
// busca.add(Expression.eq("id_hospede", id));
return (Quarto) busca;
} catch (org.hibernate.ObjectNotFoundException e) {
return null;
} catch(Exception ex){
throw new DAOException(ex);
}finally{
}
}
Ao executar o metodo ele me retorna o seguinte stackTrace: como posso corrigir este problema
http://paste-it.net/public/o55dd4e/
segue codigos fontes:
principal.jsp : http://paste-it.net/public/u1b331b/
listarQuartosAlugados.jsp: http://paste-it.net/public/xd5c29c/
QuartosAlugadosBean: http://paste-it.net/public/k3f23fc/
QuartosAlugadosDAOImpl: http://paste-it.net/public/c3cfb0c/
Marcos Sousa
Curtidas 0
Respostas
Henrique Weissmann
02/11/2010
Oi Marcos,
no caso, usando Hibernate (no seu caso, usando HQL), você não possui a instrução inner join, pois você não lida diretamente com as tabelas presentes no banco de dados, mas sim com as classes que são mapeadas para estas tabelas.
Sugiro que você leia este texto, que expõe a linguagem HQL: http://docs.jboss.org/hibernate/core/3.5/reference/pt-BR/html/queryhql.html
Como verá, os "inner joins" que você precisa são todos gerados pelo próprio Hibernate, razão pela qual não estão incluidos na linguagem.
no caso, usando Hibernate (no seu caso, usando HQL), você não possui a instrução inner join, pois você não lida diretamente com as tabelas presentes no banco de dados, mas sim com as classes que são mapeadas para estas tabelas.
Sugiro que você leia este texto, que expõe a linguagem HQL: http://docs.jboss.org/hibernate/core/3.5/reference/pt-BR/html/queryhql.html
Como verá, os "inner joins" que você precisa são todos gerados pelo próprio Hibernate, razão pela qual não estão incluidos na linguagem.
GOSTEI 0
Marcos Sousa
02/11/2010
Boa noite Henrique. Li com calma todo o capítulo 15 e tentei fazer duas HQL para o problema mais elas não foram bem sucedidas.
public Quarto consultaInformacoesQuartoAlugado(Quarto quarto) throws DAOException{
Session session = HibernateUtil.getSession();
try {
//primeira tentativa
Criteria busca =
session.createCriteria("FROM QuartosAlugados al, Quarto q "
+ "where al.id = "+quarto.getId());
return (Quarto) busca;
} catch (org.hibernate.ObjectNotFoundException e) {
return null;
} catch(Exception ex){
throw new DAOException(ex);
}finally{
}
}
De acordo com o item 15.9 clausulas where: http://paste-it.net/public/r9e80b3/
Tive como base a seguinte consulta:
select foo
from Foo foo, Bar bar
where foo.startDate = bar.date
Ele me gerou o seguinte StackTrace:
A seguir fiz esta outra tentativa
public Quarto consultaInformacoesQuartoAlugado(Quarto quarto) throws DAOException{
Session session = HibernateUtil.getSession();
try {
session.createCriteria("Select al.id, q.id FROM QuartosAlugados as al "
+ "Quarto as q "
+ "where al.id = "+quarto.getId());
// busca.add(Expression.eq("id_hospede", quarto.getId()));
return (Quarto) busca;
} catch (org.hibernate.ObjectNotFoundException e) {
return null;
} catch(Exception ex){
throw new DAOException(ex);
}finally{
}
}
Ele gerou o mesmo stackTrace anterior
Ela e uma adaptação ao seguinte HQL.
select cust
from Product prod,
Store store
inner join store.customers cust
where prod.name = 'widget'
and store.location.name in ( 'Melbourne', 'Sydney' )
and prod = all elements(cust.currentOrder.lineItems).
Alem deste problema tenho uma forte suspeita de ter um POG em uma funcionalidade do projeto.
No link listarQuartosAlugados eu faço uma consulta utilizando o managedBean QuartoBean. Ele executa o metodo da DAO
QuartosAlugadosDAOImpl chamado listarQuartosAlugados().
QuartosAlugadosDAOImpl: http://paste-it.net/public/hc6dd4d/
Meu questionamento e o seguinte na tabela de quarto eu tenho os campos:
id;numeroQuarto;StatusQuarto (disponivel, indisponivel, em manutenção);Quando o quarto estiver indisponivel significa que ele esta alugado. Esta tabela faz relacionamento com a tabela aluga_quartos nesta tabela devo gravar os quartos que foram alugados.
Neste caso eu devo fazer esta consulta buscando os quartos por esta tabela. Ou da forma que estou fazendo pode ser considerada certa?
Envio imagem do MER chamada MER sismot.
Desde já agradeço.
public Quarto consultaInformacoesQuartoAlugado(Quarto quarto) throws DAOException{
Session session = HibernateUtil.getSession();
try {
//primeira tentativa
Criteria busca =
session.createCriteria("FROM QuartosAlugados al, Quarto q "
+ "where al.id = "+quarto.getId());
return (Quarto) busca;
} catch (org.hibernate.ObjectNotFoundException e) {
return null;
} catch(Exception ex){
throw new DAOException(ex);
}finally{
}
}
De acordo com o item 15.9 clausulas where: http://paste-it.net/public/r9e80b3/
Tive como base a seguinte consulta:
select foo
from Foo foo, Bar bar
where foo.startDate = bar.date
Ele me gerou o seguinte StackTrace:
A seguir fiz esta outra tentativa
public Quarto consultaInformacoesQuartoAlugado(Quarto quarto) throws DAOException{
Session session = HibernateUtil.getSession();
try {
session.createCriteria("Select al.id, q.id FROM QuartosAlugados as al "
+ "Quarto as q "
+ "where al.id = "+quarto.getId());
// busca.add(Expression.eq("id_hospede", quarto.getId()));
return (Quarto) busca;
} catch (org.hibernate.ObjectNotFoundException e) {
return null;
} catch(Exception ex){
throw new DAOException(ex);
}finally{
}
}
Ele gerou o mesmo stackTrace anterior
Ela e uma adaptação ao seguinte HQL.
select cust
from Product prod,
Store store
inner join store.customers cust
where prod.name = 'widget'
and store.location.name in ( 'Melbourne', 'Sydney' )
and prod = all elements(cust.currentOrder.lineItems).
Alem deste problema tenho uma forte suspeita de ter um POG em uma funcionalidade do projeto.
No link listarQuartosAlugados eu faço uma consulta utilizando o managedBean QuartoBean. Ele executa o metodo da DAO
QuartosAlugadosDAOImpl chamado listarQuartosAlugados().
QuartosAlugadosDAOImpl: http://paste-it.net/public/hc6dd4d/
Meu questionamento e o seguinte na tabela de quarto eu tenho os campos:
id;numeroQuarto;StatusQuarto (disponivel, indisponivel, em manutenção);Quando o quarto estiver indisponivel significa que ele esta alugado. Esta tabela faz relacionamento com a tabela aluga_quartos nesta tabela devo gravar os quartos que foram alugados.
Neste caso eu devo fazer esta consulta buscando os quartos por esta tabela. Ou da forma que estou fazendo pode ser considerada certa?
Envio imagem do MER chamada MER sismot.
Desde já agradeço.
GOSTEI 0
Henrique Weissmann
02/11/2010
Oi Marcos.
Há algumas coisas a serem modificadas no seu código.
1. Não se usa a classe Criteria para se trabalhar com HQL, mas sim a interface org.hibernate.Query, que você pode obter da sua sessão chamando o método createQuery.
Sendo assim, o seu código atual:
Session session = HibernateUtil.getSession();
try {
//primeira tentativa
Criteria busca =
session.createCriteria("FROM QuartosAlugados al, Quarto q "
+ "where al.id = "+quarto.getId());
return (Quarto) busca;
} catch (org.hibernate.ObjectNotFoundException e) {
return null;
} catch(Exception ex){
throw new DAOException(ex);
}finally{
}
}
Precisa ser modificado para que fique tal como: esta é a primeira modificação.
Session session = HibernateUtil.getSession();
try {
//primeira tentativa
Query busca =
session.createQuery("FROM QuartosAlugados al, Quarto q "
+ "where al.id = "+quarto.getId());
return (Quarto) busca;
} catch (org.hibernate.ObjectNotFoundException e) {
return null;
} catch(Exception ex){
throw new DAOException(ex);
}finally{
}
}
Melhorando ainda mais o seu código: repare no seu return. Você está tentando retornar uma instância de QuartosAlugados, mas está fazendo o typecasting errado.
Repare neste trecho:
Query busca =
session.createQuery("FROM QuartosAlugados al, Quarto q "
+ "where al.id = "+quarto.getId());
return (Quarto) busca;
Você vai topar com um ClassCastingException, pois sua função tenta retornar uma instância de QuartosAlugados, mas você está tentando fazer a conversão de tipo Criteria para esta classe.
Novamente, eu modifico o código acima para uma segunda versão:
Session session = HibernateUtil.getSession();
try {
//primeira tentativa
Query busca =
session.createQuery("FROM QuartosAlugados al, Quarto q "
+ "where al.id = "+quarto.getId());
return (Quarto) busca.uniqueResult();
} catch (org.hibernate.ObjectNotFoundException e) {
return null;
} catch(Exception ex){
throw new DAOException(ex);
}finally{
}
}
E este seu código ainda pode ser melhorado.
Repare na sua consulta:
"FROM QuartosAlugados al, Quarto q "
+ "where al.id = "+quarto.getId())
Observe: você tem apenas uma cláusula FROM que diz que quer buscar os quartos alugados e um quarto. O resultado da consulta seria uma tupla. Novamente, a versão do código que lhe expus acima, ainda não é válida. Vou trabalhar mais um pouco nela.
Detalhe: na sua consulta HQL, você deve incluir apenas objetos que já estejam mapeados para o Hibernate. Pelo que pude entender, você está querendo buscar a listagem de quartos que estejam alugados, correto?
Para que possa lhe ajudar neste caso, preciso saber mais sobre esta sua classe: QuartosAlugados? É uma classe de domínio persistida no banco de dados? Do que se trata exatamente? Ela foi mapeada pelo Hibernate?
Pelos erros que vi no seu código Marcos, está claro que você não está com uma compreensão bacana do Hiberate. Eu sugiro que você dê uma lida rápida, não precisa se aprofundar, no link abaixo. É o tutorial do Hibernate em português. É bastante tranquilo e, como disse, não precisa se aprofundar muito. Mas só de passar os olhos você já vai ter uma noção mais clara sobre como o ORM funciona.
Segue o link: http://docs.jboss.org/hibernate/core/3.5/reference/pt-BR/html/index.html
Há algumas coisas a serem modificadas no seu código.
1. Não se usa a classe Criteria para se trabalhar com HQL, mas sim a interface org.hibernate.Query, que você pode obter da sua sessão chamando o método createQuery.
Sendo assim, o seu código atual:
Session session = HibernateUtil.getSession();
try {
//primeira tentativa
Criteria busca =
session.createCriteria("FROM QuartosAlugados al, Quarto q "
+ "where al.id = "+quarto.getId());
return (Quarto) busca;
} catch (org.hibernate.ObjectNotFoundException e) {
return null;
} catch(Exception ex){
throw new DAOException(ex);
}finally{
}
}
Precisa ser modificado para que fique tal como: esta é a primeira modificação.
Session session = HibernateUtil.getSession();
try {
//primeira tentativa
Query busca =
session.createQuery("FROM QuartosAlugados al, Quarto q "
+ "where al.id = "+quarto.getId());
return (Quarto) busca;
} catch (org.hibernate.ObjectNotFoundException e) {
return null;
} catch(Exception ex){
throw new DAOException(ex);
}finally{
}
}
Melhorando ainda mais o seu código: repare no seu return. Você está tentando retornar uma instância de QuartosAlugados, mas está fazendo o typecasting errado.
Repare neste trecho:
Query busca =
session.createQuery("FROM QuartosAlugados al, Quarto q "
+ "where al.id = "+quarto.getId());
return (Quarto) busca;
Você vai topar com um ClassCastingException, pois sua função tenta retornar uma instância de QuartosAlugados, mas você está tentando fazer a conversão de tipo Criteria para esta classe.
Novamente, eu modifico o código acima para uma segunda versão:
Session session = HibernateUtil.getSession();
try {
//primeira tentativa
Query busca =
session.createQuery("FROM QuartosAlugados al, Quarto q "
+ "where al.id = "+quarto.getId());
return (Quarto) busca.uniqueResult();
} catch (org.hibernate.ObjectNotFoundException e) {
return null;
} catch(Exception ex){
throw new DAOException(ex);
}finally{
}
}
E este seu código ainda pode ser melhorado.
Repare na sua consulta:
"FROM QuartosAlugados al, Quarto q "
+ "where al.id = "+quarto.getId())
Observe: você tem apenas uma cláusula FROM que diz que quer buscar os quartos alugados e um quarto. O resultado da consulta seria uma tupla. Novamente, a versão do código que lhe expus acima, ainda não é válida. Vou trabalhar mais um pouco nela.
Detalhe: na sua consulta HQL, você deve incluir apenas objetos que já estejam mapeados para o Hibernate. Pelo que pude entender, você está querendo buscar a listagem de quartos que estejam alugados, correto?
Para que possa lhe ajudar neste caso, preciso saber mais sobre esta sua classe: QuartosAlugados? É uma classe de domínio persistida no banco de dados? Do que se trata exatamente? Ela foi mapeada pelo Hibernate?
Pelos erros que vi no seu código Marcos, está claro que você não está com uma compreensão bacana do Hiberate. Eu sugiro que você dê uma lida rápida, não precisa se aprofundar, no link abaixo. É o tutorial do Hibernate em português. É bastante tranquilo e, como disse, não precisa se aprofundar muito. Mas só de passar os olhos você já vai ter uma noção mais clara sobre como o ORM funciona.
Segue o link: http://docs.jboss.org/hibernate/core/3.5/reference/pt-BR/html/index.html
GOSTEI 0
Marcos Sousa
02/11/2010
Boa tarde Henrique. Começo lhe respondendo a seguinte pergunta.
"Para que possa lhe ajudar neste caso, preciso saber mais sobre esta sua classe: QuartosAlugados? É uma classe de domínio persistida no banco de dados? Do que se trata exatamente? Ela foi mapeada pelo Hibernate?"
Esta classe QuartosAlugados e fruto do relacionamento NxM entre Hospede e Quarto, tenho o seguinte Relacionamento:
um hospede aluga um ou vários quartos; eum ou vários quartos e alugado por um hospede.Segue abaixo link dos codigos dos entity's Hospede, Quarto e QuartosAlugados. Ela é uma classe a ser persistida pelo banco de dados pois eu tenho que guardar as informações referentes aos quartos alugados.
Quarto:http://paste-it.net/public/kf181b2/
QuartosAlugados:http://paste-it.net/public/e237931/;
Hospede: http://paste-it.net/public/z3f171b/
Em relação ao meu conhecimento sobre hibernate é bem inicial. Irei ler o artigo que voce me enviou. Quanto aquela minha dúvida sobre estar implementando um POG no projeto, ela está acontecendo realmente?
Desde já agradeço.
"Para que possa lhe ajudar neste caso, preciso saber mais sobre esta sua classe: QuartosAlugados? É uma classe de domínio persistida no banco de dados? Do que se trata exatamente? Ela foi mapeada pelo Hibernate?"
Esta classe QuartosAlugados e fruto do relacionamento NxM entre Hospede e Quarto, tenho o seguinte Relacionamento:
um hospede aluga um ou vários quartos; eum ou vários quartos e alugado por um hospede.Segue abaixo link dos codigos dos entity's Hospede, Quarto e QuartosAlugados. Ela é uma classe a ser persistida pelo banco de dados pois eu tenho que guardar as informações referentes aos quartos alugados.
Quarto:http://paste-it.net/public/kf181b2/
QuartosAlugados:http://paste-it.net/public/e237931/;
Hospede: http://paste-it.net/public/z3f171b/
Em relação ao meu conhecimento sobre hibernate é bem inicial. Irei ler o artigo que voce me enviou. Quanto aquela minha dúvida sobre estar implementando um POG no projeto, ela está acontecendo realmente?
Desde já agradeço.
GOSTEI 0
Henrique Weissmann
02/11/2010
Oi Marcos,
bom: primeiro a respeito da sua classe QuartosAlugados. Pelo que pude entender, ela funciona como se fosse um registro do histórico de locações de quartos, certo? Por isto os atributos quarto, hospede, data de início e data de finalização da locação. Ok. Com base nela, já podemos montar algumas consultas que irão resolver o seu problema.
Porém, antes, eu gostaria de fazer algumas observações a seu respeito. No caso, o principal ponto é o seu atributo Quarto, que de cara já é iniciado com uma nova instância. Nesta situação, esta não é uma prática desejável pela seguinte razão.
Para que a classe QuartosAlugados possua sentido, antes de ser persistida, é obrigatório que o quarto já esteja persistido na base de dados. Criando uma nova instância de cara para esta variável, você pode correr o risco de, no momento em que estiver persistindo a classe, automáticamente criar uma novo registro de quarto na sua base de dados qu enão faça sentido algum.
Neste caso então, você deve substituir a sua declaração inicial:
private Quarto quarto = new Quarto();
por
private Quarto quarto;
Assim você não corre este risco. No momento em que esta classe for instanciada por um managed bean ou algo similar, ai sim, esta classe que a manipula (no caso, o managed bean) é que deverá executar o trabalho de definir o valor deste atributo pelo setter usando como valor uma instância apropriada, ou seja, um quarto que já esteja persistido na base de dados do seu sistema.
Agora, podemos tratar da consulta. Bom: esta sua função:
public Quarto consultaInformacoesQuartoAlugado(Quarto quarto) throws DAOException{
O objetivo dela, pelo que pude ver, é o de verificar se o quarto encontra-se alugado ou não, certo? Então não faz sentido que ela te retorne uma nova instância de Quarto (que já foi passado como parâmetro), mas sim um valor booleano, do tipo true ou false, indicando se o quarto está alugado ou não.
Pelo que pude ver, um quarto estará alugado se existir um registro de QuartosAlugados no seu banco de dados com data de término nula, correto? Neste caso, poderíamos reimplementá-la da seguinte maneira:
public boolean consultaInformacoesQuartoAlugado(Quarto quarto) throws DAOException {
Session session = HibernateUtil.getSession();
try {
Query busca = sessao.createQuery("from br.com.sismot.model.entity.QuartosAlugados qa where qa.quarto = :quarto and qa.dataTermino is null");
busca.setEntity("quarto", quarto);
List<QuartosAlugados> registros = busca.list();
if (registros != null && ! registros.isEmpty()) return false; else return true;
} catch (Exception ex) {
throw new ErroDAO("Erro ao verificar situação do quarto", ex);
} finally {
if (sessao != null && sessao.isOpen()) sessao.close();
}
}
Observe, a função irá retornar true caso o quarto não esteja alugado, pois não será retornado registro algum da base de dados.
Agora, não entendi a sua dúvida sobre POG. Tem como explicar melhor?
bom: primeiro a respeito da sua classe QuartosAlugados. Pelo que pude entender, ela funciona como se fosse um registro do histórico de locações de quartos, certo? Por isto os atributos quarto, hospede, data de início e data de finalização da locação. Ok. Com base nela, já podemos montar algumas consultas que irão resolver o seu problema.
Porém, antes, eu gostaria de fazer algumas observações a seu respeito. No caso, o principal ponto é o seu atributo Quarto, que de cara já é iniciado com uma nova instância. Nesta situação, esta não é uma prática desejável pela seguinte razão.
Para que a classe QuartosAlugados possua sentido, antes de ser persistida, é obrigatório que o quarto já esteja persistido na base de dados. Criando uma nova instância de cara para esta variável, você pode correr o risco de, no momento em que estiver persistindo a classe, automáticamente criar uma novo registro de quarto na sua base de dados qu enão faça sentido algum.
Neste caso então, você deve substituir a sua declaração inicial:
private Quarto quarto = new Quarto();
por
private Quarto quarto;
Assim você não corre este risco. No momento em que esta classe for instanciada por um managed bean ou algo similar, ai sim, esta classe que a manipula (no caso, o managed bean) é que deverá executar o trabalho de definir o valor deste atributo pelo setter usando como valor uma instância apropriada, ou seja, um quarto que já esteja persistido na base de dados do seu sistema.
Agora, podemos tratar da consulta. Bom: esta sua função:
public Quarto consultaInformacoesQuartoAlugado(Quarto quarto) throws DAOException{
O objetivo dela, pelo que pude ver, é o de verificar se o quarto encontra-se alugado ou não, certo? Então não faz sentido que ela te retorne uma nova instância de Quarto (que já foi passado como parâmetro), mas sim um valor booleano, do tipo true ou false, indicando se o quarto está alugado ou não.
Pelo que pude ver, um quarto estará alugado se existir um registro de QuartosAlugados no seu banco de dados com data de término nula, correto? Neste caso, poderíamos reimplementá-la da seguinte maneira:
public boolean consultaInformacoesQuartoAlugado(Quarto quarto) throws DAOException {
Session session = HibernateUtil.getSession();
try {
Query busca = sessao.createQuery("from br.com.sismot.model.entity.QuartosAlugados qa where qa.quarto = :quarto and qa.dataTermino is null");
busca.setEntity("quarto", quarto);
List<QuartosAlugados> registros = busca.list();
if (registros != null && ! registros.isEmpty()) return false; else return true;
} catch (Exception ex) {
throw new ErroDAO("Erro ao verificar situação do quarto", ex);
} finally {
if (sessao != null && sessao.isOpen()) sessao.close();
}
}
Observe, a função irá retornar true caso o quarto não esteja alugado, pois não será retornado registro algum da base de dados.
Agora, não entendi a sua dúvida sobre POG. Tem como explicar melhor?
GOSTEI 0
Marcos Sousa
02/11/2010
Minha dúvida em relação ao POG e a seguinte. Tenho no painel principal dois links:
listarQuartosDisponiveis;listarQuartosAlugados;Em ambas eu estou realizando a consulta atraves do managedBean QuartoBean. Nele tenho estes dois métodos:
listarQuartosDisponiveis;listarQuartosAlugados;Em ambos metodos faço a seguinte query de consulta ao banco de dados
session.createQuery("FROM Quarto q where q.statusQuarto like 'disponivel' order by q.categoriaQuarto"); Chamada pelo método listarQuartosDisponiveis;session.createQuery("FROM Quarto q where q.statusQuarto like 'indisponivel' order by q.categoriaQuarto"); Chamada pelo método listarQuartosIndisponiveis.Neste caso o que esta definindo se o meu Quarto esta alugado e o status em que ele se encontra 'disponivel', 'indisponivel'.
Meu questionamento e o seguinte. Neste caso para definir um quarto que esta alugado tenho que realizar uma consulta atraves do managedBean QuartosAlugadosBean, pois este representa os quartos alugados pelo motel.
listarQuartosDisponiveis;listarQuartosAlugados;Em ambas eu estou realizando a consulta atraves do managedBean QuartoBean. Nele tenho estes dois métodos:
listarQuartosDisponiveis;listarQuartosAlugados;Em ambos metodos faço a seguinte query de consulta ao banco de dados
session.createQuery("FROM Quarto q where q.statusQuarto like 'disponivel' order by q.categoriaQuarto"); Chamada pelo método listarQuartosDisponiveis;session.createQuery("FROM Quarto q where q.statusQuarto like 'indisponivel' order by q.categoriaQuarto"); Chamada pelo método listarQuartosIndisponiveis.Neste caso o que esta definindo se o meu Quarto esta alugado e o status em que ele se encontra 'disponivel', 'indisponivel'.
Meu questionamento e o seguinte. Neste caso para definir um quarto que esta alugado tenho que realizar uma consulta atraves do managedBean QuartosAlugadosBean, pois este representa os quartos alugados pelo motel.
GOSTEI 0
Henrique Weissmann
02/11/2010
Oi Marcos,
sim: ai realmente iriamos topar não com um POG.
Da então pra simplificar bastante a situação. No caso de verificar se um quarto está alugado ou não, a consulta nem precisa ser feita, visto que, ao expor o quarto, você já carrega o atributo statusQuarto com ele.
Sendo assim, você não precisa criar um método que retorne true ou false para verificar se o quarto está vago ou não. Basta verificar o valor deste atributo.
Com relação à listagem dos quartos disponíveis, é ainda mais simples. Você pode escrever uma consulta buscando apenas os quartos com o valor de status que você quer, tal como no exemplo abaixo:
public List<Quarto> listarQuartosStatus(String status) {
Session session = HibernateUtil.getSession();
try {
Query busca = session.createQuery("from br.com.sismot.model.entity.Quarto q where q.statusQuarto = :status");
busca.setString("status", status);
return busca.list()
} catch (Exception ex) {
throw new ErroDAO("Erro ao buscar quartos por status: " + status, ex);
} finally {
if (sessao != null && sessao.isOpen()) sessao.close();
}
}
sim: ai realmente iriamos topar não com um POG.
Da então pra simplificar bastante a situação. No caso de verificar se um quarto está alugado ou não, a consulta nem precisa ser feita, visto que, ao expor o quarto, você já carrega o atributo statusQuarto com ele.
Sendo assim, você não precisa criar um método que retorne true ou false para verificar se o quarto está vago ou não. Basta verificar o valor deste atributo.
Com relação à listagem dos quartos disponíveis, é ainda mais simples. Você pode escrever uma consulta buscando apenas os quartos com o valor de status que você quer, tal como no exemplo abaixo:
public List<Quarto> listarQuartosStatus(String status) {
Session session = HibernateUtil.getSession();
try {
Query busca = session.createQuery("from br.com.sismot.model.entity.Quarto q where q.statusQuarto = :status");
busca.setString("status", status);
return busca.list()
} catch (Exception ex) {
throw new ErroDAO("Erro ao buscar quartos por status: " + status, ex);
} finally {
if (sessao != null && sessao.isOpen()) sessao.close();
}
}
GOSTEI 0
Marcos Sousa
02/11/2010
Mais quando eu alugar um quarto, tenho que fazer um update na tabela de quartos e alterar o seu status de disponivel para indisponivel e gravar este quarto na tabela quartosAlugados.
Da forma que esta a estrutura fica fácil de implementar esta funcionalidade?
Da forma que esta a estrutura fica fácil de implementar esta funcionalidade?
GOSTEI 0
Henrique Weissmann
02/11/2010
Marcos, no caso, este é um outro assunto.
Para manter este tópico melhor focado, tem como você criar um novo chamado com este assunto?
Para manter este tópico melhor focado, tem como você criar um novo chamado com este assunto?
GOSTEI 0
Marcos Sousa
02/11/2010
Correto, farei a abertura do chamado para resposta sobre este questionamento.
Mais voltando a query em HQL. Como havia lhe dito estou fazendo uma consulta aos quartos alugados me baseando somente no status do quarto que encontra - se indisponivel e fazendo esta consulta na tabela de quartos.
Mais este retorno não me da uma informação 100% correta, pois dos dois quartos que eu retorno como indisponível um não está alugado.
Os status que cadastrei para os quartos são:
disponivel (Quarto disponivel para locação);indisponivel (Quarto alugado);em manutenção(Quarto indisponivel para locação, por motivos diversos).O administrador ao cadastrar os quartos tem a opção de definir o status de cada quarto de acordo com os status descrito anteriormente.
voce tem uma sugestão para que eu possa resolver este problema.
Mais voltando a query em HQL. Como havia lhe dito estou fazendo uma consulta aos quartos alugados me baseando somente no status do quarto que encontra - se indisponivel e fazendo esta consulta na tabela de quartos.
Mais este retorno não me da uma informação 100% correta, pois dos dois quartos que eu retorno como indisponível um não está alugado.
Os status que cadastrei para os quartos são:
disponivel (Quarto disponivel para locação);indisponivel (Quarto alugado);em manutenção(Quarto indisponivel para locação, por motivos diversos).O administrador ao cadastrar os quartos tem a opção de definir o status de cada quarto de acordo com os status descrito anteriormente.
voce tem uma sugestão para que eu possa resolver este problema.
GOSTEI 0
Henrique Weissmann
02/11/2010
Marcos,
neste caso, você deve verificar quais os valores estão presentes na tabela relacionada em seu banco de dados. Como você usou um valor do tipo String para este atributo, nada impede que você tenha por exemplo, valores como "alugado", "Alugado", "alugado " (o último exemplo, com um caractere de espaço).
O banco de dados faz a pesquisa levando em consideração caracteres maiúsculos, espaços, etc. É por esta razão que quando queremos representar algum status em um registro no banco de dados, normalmente opta-se por um valor inteiro, pois assim evita-se cair neste tipo de armadilha.
neste caso, você deve verificar quais os valores estão presentes na tabela relacionada em seu banco de dados. Como você usou um valor do tipo String para este atributo, nada impede que você tenha por exemplo, valores como "alugado", "Alugado", "alugado " (o último exemplo, com um caractere de espaço).
O banco de dados faz a pesquisa levando em consideração caracteres maiúsculos, espaços, etc. É por esta razão que quando queremos representar algum status em um registro no banco de dados, normalmente opta-se por um valor inteiro, pois assim evita-se cair neste tipo de armadilha.
GOSTEI 0
Devmedia
02/11/2010
Marcos,a resposta solucionou o seu problema? podemos encerrar o chamado?
GOSTEI 0
Marcos Sousa
02/11/2010
Peço um prazo, pois não tive tempo para fazer as correções sugeridas pelo Henrique
GOSTEI 0
Devmedia
02/11/2010
Marcos,
por falta de retorno estamos encerrando o chamado. Caso volte a ter dúvidas sobre o assunto aqui tratado, por favor, volte a postar aqui mesmo e o consultor voltará a lhe atender.
por falta de retorno estamos encerrando o chamado. Caso volte a ter dúvidas sobre o assunto aqui tratado, por favor, volte a postar aqui mesmo e o consultor voltará a lhe atender.
GOSTEI 0