JSF + hibernate com SQLQuery

7 respostas
R

Bom dia!!!

Minha classe DAO tem a seguinte consulta:
public List<Categorias> agrupaCategorias() {
		Query q = getSession().createSQLQuery(" SELECT categorias.NOME, Count(categorias.NOME) AS contador " +
												" FROM categorias INNER JOIN (perg_resp_vinculados INNER JOIN faq ON perg_resp_vinculados.ID_PERGUNTA = faq.ID) ON categorias.id = faq.categoria_ID " +
												" GROUP BY categorias.NOME; ")		
				.addEntity(Categorias.class);
		return q.list();
	}
chamada assim:
CategoriasDAO dao = new CategoriasDAO();
			relatorioCategoria = dao.agrupaCategorias();
e o seguinte erro acontece:
Grave: Error Rendering View[/relatorioCategoria.xhtml]
javax.el.ELException: /relatorioCategoria.xhtml @27,71 value="#{acompanhamentosBean.relatorioCategoria}": Error reading 'relatorioCategoria' on type br.com.bb.gefin.atendTel.controle.AcompanhamentosBean
	at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
	at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:193)
	at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:181)
	at javax.faces.component.UIData.getValue(UIData.java:557)
	at javax.faces.component.UIData.getDataModel(UIData.java:1297)
	at javax.faces.component.UIData.getRowCount(UIData.java:342)
	at org.primefaces.component.datatable.DataTable.calculatePage(DataTable.java:769)
	at org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:160)
	at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:85)
	at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:883)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1659)
	at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
	at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:853)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1652)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1655)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1655)
	at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:399)
	at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
	at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at br.com.bb.gefin.filtro.HibernateSessionRequestFilter.doFilter(HibernateSessionRequestFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:539)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:298)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: org.hibernate.exception.SQLGrammarException: could not execute query
	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
	at org.hibernate.loader.Loader.doList(Loader.java:2536)
	at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
	at org.hibernate.loader.Loader.list(Loader.java:2271)
	at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:316)
	at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1842)
	at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:165)
	at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:157)
	at br.com.bb.gefin.atendTel.dao.CategoriasDAO.agrupaCategorias(CategoriasDAO.java:34)
	at br.com.bb.gefin.atendTel.controle.AcompanhamentosBean.getRelatorioCategoria(AcompanhamentosBean.java:927)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at javax.el.BeanELResolver.getValue(BeanELResolver.java:87)
	at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
	at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
	at org.apache.el.parser.AstValue.getValue(AstValue.java:169)
	at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
	at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
	... 43 more
Caused by: java.sql.SQLException: Column 'ID' not found.
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
	at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1144)
	at com.mysql.jdbc.ResultSetImpl.getInt(ResultSetImpl.java:2793)
	at com.mchange.v2.c3p0.impl.NewProxyResultSet.getInt(NewProxyResultSet.java:2573)
	at org.hibernate.type.descriptor.sql.IntegerTypeDescriptor$2.doExtract(IntegerTypeDescriptor.java:61)
	at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64)
	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253)
	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:249)
	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:229)
	at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:330)
	at org.hibernate.loader.Loader.extractKeysFromResultSet(Loader.java:668)
	at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:606)
	at org.hibernate.loader.Loader.doQuery(Loader.java:829)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
	at org.hibernate.loader.Loader.doList(Loader.java:2533)
	... 61 more
sendo que minhas classes:
public class Categorias implements Serializable{
	
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column (name="ID")
	private Integer id;
	
	@OneToMany(mappedBy="categoria")
	private List<Faq> faq;
	
	@Column (name="NOME", nullable=true, length=50)
	private String nome;
	
	@Column (name="CONTADOR")
	private Long contador;


public class Faq implements Serializable{
	
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column (name="ID")
	private Integer id;
	
	@ManyToOne
	private Categorias categoria;
	
	@Column (name="RESPOSTA", nullable=true)
	@Type(type="text")
	private String resposta;
	
	@Column (name="PERGUNTA", nullable=true, length=255)
	private String pergunta;

	@Column (name="INC", nullable=true, length=100)
	private String inc;


public class PergRespVinculados implements Serializable{
	
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column (name="ID")
	private Long id;
	
	//id faq
	
	@Column (name="PERGUNTA", nullable=true, length=255)
	private String pergunta;
	
	@Column (name="RESPOSTA")
	@Type(type="text")
	private String resposta;
	
	@ManyToOne
	private Chamadas chamadas;
	
	@Column (name="ID_PERGUNTA")
	private Integer idPergunta;
	
	@Column (name="SCRIPT_IGUAL_RESPOSTA")
	private Boolean scriptIgualResposta;
	
	@Column (name="SCRIPT_IGUAL_PERGUNTA")
	private Boolean scriptIgualPergunta;

Tem ID onde pede ID...

Não sei o que está acontecendo, até pq quando eu faço o SQL no MYSQL direto, ele executa minha consulta.

Alguém sabe o que é isto?

Grato!!

7 Respostas

D

Camarada, me parece que ele está implicando com o tipo de caixa utilizado.
Na query você define “categoria.id” como minúsculo e no mapeamento, “ID” maiúsculo.

É a única coisa que vejo ser diferente aí. Posso estar falando uma grande bobagem.

R

não é bobagem… mas é uma idéia!!

eu coloquei minusculo nele e depois no outro só pra tentar achar em qual dos dois ele estava reclamando, mas mesmo assim não localizei…

o erro sempre retorna que não achou o “ID” mesmo mudando p/ faq.id e categoria.id

a query original era toda maiuscula e não funciona…

Obrigado pela tentativa!

E

não lembro bem mas o createSQLQuery é o equivalente ao createNativeQuery do JPA certo? o addEntity é para retornar um objeto de Categorias certo? Se é para retornar um objeto de Categorias, mapeado pela base de dados, porque não tem uma coluna “ID” no retorno para ele saber qual “Categorias” é? Acho que é isso que ele está reclamando.

E

repare nessas linhas do erro:

Caused by: java.sql.SQLException: Column ‘ID’ not found.

at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)

at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)

at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)

at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1144)

at com.mysql.jdbc.ResultSetImpl.getInt(ResultSetImpl.java:2793)
R

verdade…
deve ser isto mesmo!!

mas o problema que se eu pedir pra retornar o id não da pra eu agrupar como eu quero… vou ter que criar uma classe só pra isso né?

E

não precisa criar uma classe só para isso (se não quiser). Você poderia, por exemplo, retornar na consulta um List<Object[]> (se não passar nenhuma classe)

Mas se quiser usar alguma classe, se me lembro bem você pode fazer algo assim:

public class Categorias{
 //seu código da classe
  public static class CategoriasCount{

    String name;
    Integer cont;

    public CategoriasCount(String name, Integer cont){
       this.name = name;
       this.cont = cont;
    }

  }
  // seu código da classe
}

E no HQL (essa consulta pode facilmente ser passada para HQL), você coloca assim:

SELECT new Categorias.CategoriasCount(name, count(name))
  -- resto do seu SQL

Mas nunca trabalhei com Hibernate, só com EclipseLink, portanto não sei bem se é assim.

R

com outra classe eu resolvi...
fiz praticamente do jeito q você colocou sem o construtor

public class RelatorioCategorias implements Serializable{
	
	private static final long serialVersionUID = 1L;
	
	private String nome;
	private BigInteger contador;

só mudei o tipo pra BigInteger pois era o que vinha retornando da minha query...

e minha classe não é uma entidade, então usei um result transformer

public List<RelatorioCategorias> agrupaCategorias() {
		Query q = getSession().createSQLQuery(" SELECT categorias.NOME AS nome, Count(categorias.NOME) AS contador " +
												" FROM categorias INNER JOIN (perg_resp_vinculados INNER JOIN faq ON perg_resp_vinculados.ID_PERGUNTA = faq.ID2) ON categorias.ID2 = faq.categoria_ID " +
												" GROUP BY categorias.NOME " + 
												" ORDER BY contador DESC;")	;	
				//.addEntity(RelatorioCategorias.class);
		q.setResultTransformer(Transformers.aliasToBean(RelatorioCategorias.class));
		return q.list();
	}

Gostaria muito de usar a mesma classe, mas o problema que eu vejo de uma list é que eu não consigo em uma página JSF(quando eu digo que não consigo, é que não sei se tem como e como faz..) chamar meus atributos...

hoje em dia é assim:
<p:column sortBy="#{chamadas.nome}" 
					filterBy="#{chamadas.nome}" 
					filterMatchMode="contains" style="padding: 2px">
					<f:facet name="header">
						<h:outputText value="Categoria"/>
					</f:facet>
		            <h:outputText value="#{chamadas.nome}" />					
				</p:column>
				
				<p:column sortBy="#{chamadas.contador}" style="padding: 2px;text-align:right">
					<f:facet name="header">
						<h:outputText value="Qtde. "/>
					</f:facet>
		            <h:outputText value="#{chamadas.contador}" />					
				</p:column>

pois eu tenho os alias de contar e nome, com a lista de object eu não sei como por pra chamar...

Criado 22 de junho de 2012
Ultima resposta 22 de jun. de 2012
Respostas 7
Participantes 3