Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

NamedQuery com problema de compilação

Olá,

Após recortar do método antigo do JPQL para o NamedQuery, conforme mostrado abaixo:

@NamedQuery(name="Produto.produtosPorCategoria", query="SELECT p FROM Produto p WHERE p.categoria.nome = :nome")

porém obtenho o seguinte erro:

ERROR: HHH000177: Error in named query: Produto.produtosPorCategoria
org.hibernate.QueryException: could not resolve property: nome of: br.com.alura.loja.modelo.Categoria [SELECT p FROM br.com.alura.loja.modelo.Produto p WHERE p.categoria.nome = :nome]
    at org.hibernate.QueryException.generateQueryException(QueryException.java:120)
    at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:220)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73)
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:162)
    at org.hibernate.query.spi.NamedQueryRepository.checkNamedQueries(NamedQueryRepository.java:159)
    at org.hibernate.internal.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:553)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:327)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:469)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at br.com.alura.loja.util.JPAUtil.<clinit>(JPAUtil.java:13)
    at br.com.alura.loja.testes.CadastroPedido.popularbancodedados(CadastroPedido.java:88)
    at br.com.alura.loja.testes.CadastroPedido.main(CadastroPedido.java:23)
Caused by: org.hibernate.QueryException: could not resolve property: nome of: br.com.alura.loja.modelo.Categoria
    at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:77)
    at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:71)
    at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:2043)
    at org.hibernate.hql.internal.ast.tree.FromElementType.getPropertyType(FromElementType.java:412)
    at org.hibernate.hql.internal.ast.tree.FromElement.getPropertyType(FromElement.java:520)
    at org.hibernate.hql.internal.ast.tree.DotNode.getDataType(DotNode.java:694)
    at org.hibernate.hql.internal.ast.tree.DotNode.prepareLhs(DotNode.java:269)
    at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:209)
    at org.hibernate.hql.internal.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:1053)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1303)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4771)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:4237)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2161)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:827)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:621)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:325)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:273)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:276)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192)
    ... 15 more
5 respostas

Oi Anderson,

posta aqui o codigo da sua classe Categoria, pois pela mensagem de erro nela nao tem o atributo nome.

Segue o código:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "categorias")
public class Categoria {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String categoria;

    //OBRIGATORIO
    public Categoria() {

    }

    public Categoria(String categoria) {
        this.categoria = categoria;
    }

    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getCategoria() {
        return categoria;
    }
    public void setCategoria(String categoria) {
        this.categoria = categoria;
    }
}

Eu aproveitei e coloquei o atributo nome, some o aviso de erro, contudo, quando executo a classe CadastroDeProdutos.java aparece o seguinte erro:

jul 11, 2021 1:17:49 PM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: 
    insert 
    into
        produtos
        (id, categoria_id, dataCadastro, descricao, nome, preco) 
    values
        (null, ?, ?, ?, ?, ?)
Exception in thread "main" java.lang.IllegalStateException: Cannot begin Transaction on closed Session/EntityManager
    at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:63)
    at br.com.alura.loja.testes.CadastroDeProdutos.main(CadastroDeProdutos.java:50)
solução!

Oi Anderson,

Era isso mesmo, na sua classe Categoria o atributo nao se chaamva nome, mas sim categoria.

Agora posta o codigo da sua classe CadastroDeProdutos, pois parece que voce ta chamando uma operacao no entityManager depois que a session ja foi fechada.

Opa, era isso mesmo, obrigado professor! Eu havia fechado a conexão do EntityManager e tentava abrir novamente ela depois, segue o código corrigido:

import java.math.BigDecimal;

import javax.persistence.EntityManager;

import br.com.alura.dao.ProdutoDAO;
import br.com.alura.loja.modelo.Produto;
import br.com.alura.loja.util.JPAUtil;

public class CadastroDeProdutos {
    public static void main(String[] args) {
        Produto celular = new Produto();

        celular.setNome("Xiaomi Redmi 8");
        celular.setDescricao("Muito legal");
        celular.setPreco(new BigDecimal("800"));



        /* COMO NO PERSISTENCE UNIT FOI DEFINIDO QUE AS TRANSAÇÕES
         *  SERIAM GERENCIADAS LOCALMENTE E NÃO GERIDAS POR UM SERVIDOR,
         *  CERTIFICADO PELA ORACLE, FICAMOS OBRIGADO A INDICAR QUANDO SE ABRE
         *  E FECHA AS TRANSAÇÕES 
        */

        /**
         * A propriedade a seguir tem as seguintes tipos
         *
         * Propriedade:
         //<property name="hibernate.hbm2ddl.auto" value="update" />
         * 
         * cria e atualiza atributos das tabelas (update)
         * apaga tudo e cria do zero (create)
         * cria as tabelas, mas assim que finalizar o programa já dropa (create-drop)
         * só valida se as estruturas estão ok e gera um log (validate)
         */

        EntityManager em = JPAUtil.getEntityManager();

        em.getTransaction().begin();
        em.persist(celular);
        em.getTransaction().commit();
//        em.close();


        //-----------------------

        ProdutoDAO dao = new ProdutoDAO(em);

        em.getTransaction().begin();

        dao.cadastrar(celular);

        em.getTransaction().commit();
        em.close();

        System.out.println("Obrigado pelo ótimo suporte, Professor!");

    }
}