org.hibernate.hql.internal.ast.QuerySyntaxException: a tabela não está mapeada


99

Eu tenho um exemplo de aplicativo da web Hibernate 4.3.5 + banco de dados Derby 10.10.1.1+ Glassfish4.0 com IDE NetBeans 8.0Beta.

Tenho a próxima exceção:

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: CUSTOMERV is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:189)
at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:109)
at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:95)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:331)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3633)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3522)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:706)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:562)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:247)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
... 72 more 

Formulário de index.xhtml

<h:panelGrid id="panel1" columns="2" border="1"
                 cellpadding="5" cellspacing="1">
        <f:facet name="header">
            <h:outputText value="Add Customer Information"/>
        </f:facet>
        <h:outputLabel value="First Name:"/>
        <h:inputText value="#{customer.firstName}" id="fn"/>
        <h:outputLabel value="Last Name:"/>
        <h:inputText value="#{customer.lastName}" id="ln"/>
        <h:outputLabel value="Email:"/>
        <h:inputText value="#{customer.email}" id="eml"/>
        <h:outputLabel value="Date of Birth:"/>
        <h:inputText value="#{customer.sd}" id="s"/>
        <f:facet name="footer">
            <h:outputLabel value="#{customer.msg}" id="msg" styleClass="msg"/>
            <h:commandButton value="Save" action="#{customer.saveCustomer}">
            </h:commandButton>
        </f:facet>
    </h:panelGrid> 

Customer.java

    package com.javaknowledge.entity;

    import com.javaknowledge.dao.CustomerDao;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.SessionScoped;
    import javax.persistence.*;    

    @ManagedBean
    @SessionScoped

    public class Customer implements java.io.Serializable {

    private Integer custId;
    private String firstName;
    private String lastName;
    private String email;
    private Date dob;
    private String sd, msg, selectedname;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");


    public Customer() {
    }

    public Customer(String firstName, String lastName, String email, Date dob) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.dob = dob;
    }

    public String getSd() {
        return sd;
    }

    public void setSd(String sd) {
        this.sd = sd;
    }

    public Integer getCustId() {
        return this.custId;
    }

    public void setCustId(Integer custId) {
        this.custId = custId;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    @Column(name = "EMAIL")
    public String getEmail() {
        return this.email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Column(name = "DOB")
    public Date getDob() {
        return this.dob;
    }

    public void setDob(Date dob) {
        this.dob = dob;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getSelectedname() {
        return selectedname;
    }

    public void setSelectedname(String selectedname) {
        this.selectedname = selectedname;
    }

    public void saveCustomer() {
        try {
            Date d = sdf.parse(sd);
            System.out.println(d);
            this.dob = d;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        CustomerDao dao = new CustomerDao();
        dao.addCustomer(this);
        this.msg = "Member Info Saved Successfull!";
        clearAll();
    }
    public void updateCustomer() {
        try {
            Date d = sdf.parse(sd);
            System.out.println(d);
            this.dob = d;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        CustomerDao dao = new CustomerDao();
        dao.updateCustomer(this);
        this.msg = "Member Info Update Successfull!";
        clearAll();
    }
    public void deleteCustomer() {
        CustomerDao dao = new CustomerDao();
        dao.deleteCustomer(custId);
        this.msg = "Member Info Delete Successfull!";
        clearAll();
    }

    public List<Customer> getAllCustomers() {
        List<Customer> users = new ArrayList<Customer>();
        CustomerDao dao = new CustomerDao();
        users = dao.getAllCustomers();
        return users;
    }

    public void fullInfo() {
        CustomerDao dao = new CustomerDao();
        List<Customer> lc = dao.getCustomerById(selectedname);
        System.out.println(lc.get(0).firstName);
        this.custId = lc.get(0).custId;
        this.firstName = lc.get(0).firstName;
        this.lastName = lc.get(0).lastName;
        this.email = lc.get(0).email;
        this.dob = lc.get(0).dob;
        this.sd = sdf.format(dob);
    }

    private void clearAll() {
        this.firstName = "";
        this.lastName = "";
        this.sd = "";
        this.email = "";
        this.custId=0;
    }

   }

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
    <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
    <property name="hibernate.connection.url">jdbc:derby://localhost:1527/derbyDB</property>
    <property name="hibernate.connection.username">user1</property>
    <property name="hibernate.connection.password">user1</property>
    <property name="hibernate.hbm2ddl.auto">create</property>

    <property name="c3p0.min_size">1</property>
    <property name="c3p0.max_size">5</property>
    <property name="c3p0.timeout">300</property>
    <property name="c3p0.max_statements">50</property>
    <property name="c3p0.idle_test_period">300</property>

    <mapping class="com.javaknowledge.entity.Customer" resource="com/javaknowledge/entity/Customer.hbm.xml"/>
  </session-factory>
</hibernate-configuration>

Customer.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="com.javaknowledge.entity.Customer" table="CUSTOMERV" schema="APP">
        <id name="custId" type="java.lang.Integer">
            <column name="cust_id" />
            <generator class="increment" />
        </id>
        <property name="firstName" type="string">
            <column name="first_name" length="45" not-null="true" />
        </property>
        <property name="lastName" type="string">
            <column name="last_name" length="45" not-null="true" />
        </property>
        <property name="email" type="string">
            <column name="email" length="45" not-null="true" />
        </property>
        <property name="dob" type="date">
            <column name="dob" length="10" not-null="true" />
        </property>
   </class>
</hibernate-mapping>

Respostas:


125

Finalmente encontrei um erro! Espero que isso seja útil para alguém. Ao fazer uma solicitação ao banco de dados (no meu caso é Apache Derby), o nome da base precisa escrever a primeira letra maiúscula outra em minúscula.

Esta é uma consulta errada:

session.createQuery("select first_name from CUSTOMERV").

Esta é uma consulta válida

session.createQuery("select first_name from Customerv"). 

E a entidade de classe deve ter o mesmo nome do banco de dados, mas não tenho certeza.


44
Essa pode não ser a razão. Selecione c do Cliente c esta é uma boa consulta, pois o Cliente é o nome da sua classe e devemos escrever o nome da classe na consulta, não o nome da tabela. Outra coisa em seu hibernate.cfg.xml, você forneceu <recurso de mapeamento e classe> apenas um seria ótimo. Por favor, verifique com isso.
Shoaib Chikate de

Obrigado pelo conselho Shoalib Chikate!
Vlad Dobrydin de


5
Ótimo, a única coisa que funcionou para mim foi apenas usar o nome da classe bem formatado em vez do próprio nome da tabela do banco de dados. Acho que o Hibernate requer isso para poder fazer um mapeamento adequado. É um pouco confuso e não da maneira usual como com JDBC, mas espero que versões futuras tentem gostar desse problema. Seria uma vantagem manter algum estilo do JDBC para alguns desses mecanismos de consulta.
Akah

3
Obrigado. Funcionou para mim Na verdade, leva o nome da entidade / classe, não o nome da tabela. Por exemplo: se o nome da sua tabela for CUSTOMER e o nome da sua entidade for Customer, ele incluirá o Customer na consulta, pois é uma consulta HQL.
Terry

56

na consulta HQL , não escreva o nome da tabela , escreva o nome da sua classe de entidade em sua consulta, como

String s = "from Entity_class name";
query qry = session.createUqery(s);

1
Você salvou meu tempo e também minha vida (*> *)
Ved Prakash

19

No meu caso, apenas esqueci de adicionar nativeQuery = true

@Query( value = "some sql query ...", nativeQuery = true)

Para Spring Boot com Spring Data JPA


1
Obrigado! o mesmo aconteceu comigo agora :)
ensaio

12

O arquivo hibernate.cfg.xml deve ter o mapeamento para as tabelas como abaixo. Verifique se ele está faltando em seu arquivo.

......
<hibernate-configuration>
......
......
  <session-factory>
......
<mapping class="com.test.bean.dbBean.testTableHibernate"/>
......
 </session-factory>

</hibernate-configuration>
.....

1
este foi o meu caso, ao mudar a implementação para trabalhar com Oracle DB em vez de Derby - com Derby, por algum motivo, declarar entidades em persistence.xml não era necessário (parecia lógico para mim, uma vez que as entidades já estavam anotadas) (talvez isso foi por causa de um driver mais antigo (ojdbc6))
hello_earth

11

Se você estiver usando as anotações JPA para criar as entidades, certifique-se de que o nome da tabela seja mapeado junto com a anotação @Table em vez de @Entity.

Mapeado incorretamente:

@Entity(name="DB_TABLE_NAME")
public class DbTableName implements Serializable {
   ....
   ....
}

Entidade mapeada corretamente:

@Entity
@Table(name="DB_TABLE_NAME")
public class DbTableName implements Serializable {
   ....
   ....
}

3
Obrigado! Essa foi exatamente a minha versão do problema.
Martin McCallion de

1
Obrigado. Muito útil. Continue ajudando os outros
mukesh krishnan

4

Pode ser que isso torne tudo mais claro e, claro, também faça sentido.

@Entity
@Table(name = "users")

/**
 * 
 * @author Ram Srinvasan
 * Use class name in NamedQuery
 * Use table name in NamedNativeQuery
 */
@NamedQueries({ @NamedQuery(name = "findUserByName", query = "from User u where u.name= :name") })

@NamedNativeQueries({ @NamedNativeQuery(name = "findUserByNameNativeSQL", query = "select * from users u where u.name= :name", resultClass = User.class) })
public class User implements Principal {
...
}

4

Nenhuma das outras soluções funcionou para mim.

Mesmo que eu não ache que seja a prática recomendada, tive que adicioná-lo ao código assim

configuration.addAnnotatedClass(com.myOrg.entities.Person.class);

aqui

public static SessionFactory getSessionFactory() {
    Configuration configuration = new Configuration().configure();

    configuration.addAnnotatedClass(com.myOrg.entities.Person.class);

    StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
            .applySettings(configuration.getProperties());
    SessionFactory sessionFactory = configuration.buildSessionFactory(builder.build());
    return sessionFactory;
}

3

Há mais uma chance de obter essa exceção mesmo que tenhamos usado o nome da classe, ou seja, se tivermos duas classes com o mesmo nome em pacotes diferentes. nós vamos resolver esse problema.

Acho que o hibernate pode ter ambigüidade e lançar essa exceção, então a solução é usar o nome qualificado completo (como com.test.Customerv )

Eu adicionei esta resposta que ajudará no cenário como mencionei. Eu tenho o mesmo cenário preso há algum tempo.


3

Eu também enfrentei um problema semelhante quando comecei a trabalhar no Hibernate. Tudo que posso dizer é que no createQuery é preciso passar o nome da classe de entidade, não o nome da tabela para a qual a entidade está mapeada.


2

Isso significa que sua tabela não está mapeada para o JPA. Ou o nome da tabela está errado (talvez faça distinção entre maiúsculas e minúsculas) ou você precisa inserir uma entrada no arquivo XML.

Happy Coding :)


em qual arquivo xml?
Subrahmanyam Janapamula

2

Outras pessoas que estão usando classes de mapeamento para Hibernate, certifique-se de ter endereçado corretamente para modelar o pacote na sessionFactorydeclaração do bean na seguinte parte:

<property name="packagesToScan" value="com.mblog.model"></property>

Tive esse problema com o micronauta quando esqueci de alterar packages-to-scanmeu application.ymlarquivo de configuração.
Ibrahim.H

1

Se você por acaso estiver usando java para configuração, pode ser necessário verificar a beandeclaração abaixo se houver alterações no nível do pacote. Ex: com.abc.springpacote alterado paracom.bbc.spring

@Bean
    public SessionFactory sessionFactory() {

        LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource());
        //builder.scanPackages("com.abc.spring");    //Comment this line as this package no longer valid.
        builder.scanPackages("com.bbc.spring");
        builder.addProperties(getHibernationProperties());

        return builder.buildSessionFactory();
    }

1

No meu caso: spring boot 2, múltiplas fontes de dados (padrão e customizada). entityManager.createQuerydar errado: 'a entidade não está mapeada'

durante a depuração, descobri que o unitName do entityManager está errado (deve ser personalizado, mas o fato é o padrão) da maneira certa:

@PersistenceContext(unitName = "customer1") // !important, 
private EntityManager em;

o customer1é a partir da segunda classe de fonte de dados de configuração:

@Bean(name = "customer1EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
        @Qualifier("customer1DataSource") DataSource dataSource) {
    return builder.dataSource(dataSource).packages("com.xxx.customer1Datasource.model")
            .persistenceUnit("customer1")
            // PersistenceUnit injects an EntityManagerFactory, and PersistenceContext
            // injects an EntityManager.
            // It's generally better to use PersistenceContext unless you really need to
            // manage the EntityManager lifecycle manually.
            // 【4】
            .properties(jpaProperties.getHibernateProperties(new HibernateSettings())).build();
}

Então, o entityManager está certo.

Mas, em.persist (entidade) não funciona, e a transação não funciona.

Outro ponto importante é:

@Transactional("customer1TransactionManager") // !important
public Trade findNewestByJdpModified() {
    //test persist,working right!
    Trade t = new Trade();
    em.persist(t);
    log.info("t.id" + t.getSysTradeId());

    //test transactional, working right!
    int a = 3/0;
}

customer1TransactionManager é da segunda classe de configuração da fonte de dados:

@Bean(name = "customer1TransactionManager")
public PlatformTransactionManager transactionManager(
        @Qualifier("customer1EntityManagerFactory") EntityManagerFactory entityManagerFactory) {
    return new JpaTransactionManager(entityManagerFactory);
}

Toda a segunda classe de configuração da fonte de dados é:

package com.lichendt.shops.sync;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "customer1EntityManagerFactory", transactionManagerRef = "customer1TransactionManager",
        // 【1】这里写的是DAO层的路径 ,如果你的DAO放在 com.xx.DAO下面,则这里写成 com.xx.DAO
        basePackages = { "com.lichendt.customer1Datasource.dao" })
public class Custom1DBConfig {

    @Autowired
    private JpaProperties jpaProperties;

    @Bean(name = "customer1DatasourceProperties")
    @Qualifier("customer1DatasourceProperties")
    @ConfigurationProperties(prefix = "customer1.datasource")
    public DataSourceProperties customer1DataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean(name = "customer1DataSource")
    @Qualifier("customer1DatasourceProperties")
    @ConfigurationProperties(prefix = "customer1.datasource") //
    // 【2】datasource配置的前缀,对应上面 【mysql的yaml配置】
    public DataSource dataSource() {
        // return DataSourceBuilder.create().build();
        return customer1DataSourceProperties().initializeDataSourceBuilder().build();
    }

    @Bean(name = "customer1EntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
            @Qualifier("customer1DataSource") DataSource dataSource) {
        return builder.dataSource(dataSource).packages("com.lichendt.customer1Datasource.model") // 【3】这里是实体类的包路径
                .persistenceUnit("customer1")
                // PersistenceUnit injects an EntityManagerFactory, and PersistenceContext
                // injects an EntityManager.
                // It's generally better to use PersistenceContext unless you really need to
                // manage the EntityManager lifecycle manually.
                // 【4】
                .properties(jpaProperties.getHibernateProperties(new HibernateSettings())).build();
    }

    @Bean(name = "customer1TransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("customer1EntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

mostra como configurar múltiplas fontes de dados com springboot 2.
hatanooh

0

O problema foi parcialmente resolvido. Além de criar jdbc / resource (DB Derby), foi necessário criar JDBC Connection Pool para db resource no console de administração Glassfish e verificá-lo no ping. Agora todas as operações CRUD funcionam perfeitamente. Eu verifico, questiono o cliente no banco de dados adicionando corretamente, atualizo e excluo também. Mas no log de saída do Glassfish tem a mesma exceção:

SEVERE:   org.hibernate.hql.internal.ast.QuerySyntaxException: CUSTOMERV is not mapped [select concat(first_name, ' ', last_name) as name from CUSTOMERV]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.generateQueryException(QuerySyntaxException.java:96)
    at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:120)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:234)
    .......

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: CUSTOMERV is not mapped
    at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:189)
    at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:109)

1
Sugira abrir uma nova pergunta ... esta não é uma resposta para a primeira pergunta ... ou aprimore sua primeira pergunta com a palavra
Pipo

0

Deve usar o nome da classe Entity para o método em.createQuery ou deve usar o método em.createNativeQuery para a consulta nativa sem classe de entidade

Com classe Entity:

em.createQuery ("selecionar first_name de CUSTOMERV")

Sem classe de entidade ou consulta nativa:

em.createNativeQuery ("selecione c.first_name de CUSTOMERV c")


0

No Apache Derby DB, evite usar nomes de tabela como "usuário" ou algo assim, porque são palavras-chave reservadas no Apache Derby, mas funcionarão bem no MySql.

Na Consulta, você deve especificar o nome da classe Entidade da qual deseja buscar os dados na cláusula FROM da Consulta.

List<User> users=session.createQuery("from User").list();

Aqui, User é o nome da minha classe Java Entity (considere a capitalização do nome como em Java é importante.)


0

Outra solução que funcionou:

O objeto de acesso a dados que realmente lançou essa exceção é

public List<Foo> findAll() {
    return sessionFactory.getCurrentSession().createQuery("from foo").list();
}

O erro que cometi no snippet acima é que usei o nome da tabela foo dentro de createQuery. Em vez disso, usei Foo, o nome real da classe.

public List<Foo> findAll() {
    return sessionFactory.getCurrentSession().createQuery("from Foo").list();

Graças a este blog: https://www.arundhaj.com/blog/querysyntaxexception-not-mapped.html


0

Outras pessoas que estão usando classes de mapeamento para Hibernate, certifique-se de ter endereçado corretamente o pacote de modelo na declaração do bean sessionFactory na seguinte parte:

public List<Book> list() {
    List<Book> list=SessionFactory.getCurrentSession().createQuery("from book").list();
    return list;
}

O erro que cometi no snippet acima é que usei o nome da tabela foo dentro de createQuery. Em vez disso, usei Foo, o nome real da classe.

public List<Book> list() {                                                                               
    List<Book> list=SessionFactory.getCurrentSession().createQuery("from Book").list();
    return list;
}

0

adicionar parâmetro nativeQuery = true

ex: @Query (value = "Update user set user_name =: user_name, password =: password onde user_id =: user_id", nativeQuery = true)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.