org.hibernate.hql.internal.ast.QuerySyntaxException : 테이블이 매핑되지 않음
IDE NetBeans 8.0Beta를 사용하는 웹 애플리케이션 Hibernate 4.3.5 + Derby 데이터베이스 10.10.1.1+ Glassfish4.0 예제가 있습니다.
다음 예외가 있습니다.
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
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>
마침내 실수를 발견했습니다! 이것이 누군가에게 유용하기를 바랍니다. 데이터베이스 (내 경우 Apache Derby)에 대한 요청을 할 때 기본 이름은 소문자로 된 첫 글자를 대문자로 작성해야합니다.
이것은 잘못된 쿼리입니다.
session.createQuery("select first_name from CUSTOMERV").
유효한 쿼리입니다.
session.createQuery("select first_name from Customerv").
그리고 클래스 엔티티는 데이터베이스와 동일한 이름이어야하지만 확실하지 않습니다.
에 HQL의 쿼리, 음주 아니라 쓰기 테이블 이름을 , 당신의 쓰기 Entity 클래스 이름 처럼 쿼리
String s = "from Entity_class name";
query qry = session.createUqery(s);
hibernate.cfg.xml 파일은 아래와 같은 테이블에 대한 매핑을 가져야합니다. 파일에 누락되었는지 확인하십시오.
......
<hibernate-configuration>
......
......
<session-factory>
......
<mapping class="com.test.bean.dbBean.testTableHibernate"/>
......
</session-factory>
</hibernate-configuration>
.....
JPA 어노테이션을 사용하여 엔티티를 작성하는 경우 테이블 이름이 @Entity 대신 @Table 어노테이션과 함께 맵핑되는지 확인하십시오.
잘못 매핑 :
@Entity(name="DB_TABLE_NAME")
public class DbTableName implements Serializable {
....
....
}
올바르게 매핑 된 엔티티 :
@Entity
@Table(name="DB_TABLE_NAME")
public class DbTableName implements Serializable {
....
....
}
이것이 더 명확해질 수 있으며 물론 의미가 있습니다.
@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 {
...
}
클래스 이름을 사용한 경우에도이 예외가 발생할 수있는 기회가 한 번 더 있습니다. 즉, 다른 패키지에 같은 이름을 가진 두 개의 클래스가있는 경우입니다. 이 문제가 발생합니다.
최대 절전 모드가 모호함을 얻고이 예외를 throw 할 수 있으므로 해결책은 완전한 정규화 된 이름 (예 : com.test.Customerv )을 사용하는 것입니다.
내가 언급했듯이 시나리오에서 도움이 될이 답변을 추가했습니다. 같은 시나리오가 얼마 동안 멈췄습니다.
다른 솔루션 중 어느 것도 나를 위해 일하지 않았습니다.
최선의 방법이라고 생각하지 않더라도 이렇게 코드 에 추가해야 했어요
configuration.addAnnotatedClass(com.myOrg.entities.Person.class);
여기
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;
}
Hibernate에서 작업을 시작했을 때 나도 비슷한 문제에 직면했습니다. 내가 말할 수있는 모든 것은 createQuery에 엔티티가 매핑되는 테이블 이름이 아닌 엔티티 클래스의 이름을 전달해야한다는 것입니다.
혹시 설정을 위해 java를 사용한다면, bean
패키지 레벨 변경이 있다면 아래 선언 을 확인해야 할 수도 있습니다 . 예 : com.abc.spring
패키지가 다음으로 변경됨com.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();
}
테이블이 JPA에 매핑되지 않았 음을 의미합니다. 테이블 이름이 잘못되었거나 (대소 문자 구분) XML 파일에 항목을 입력해야합니다.
해피 코딩 :)
Hibernate에 대한 매핑 클래스를 사용하는 다른 사람들 은 다음 부분 에서 빈 선언의 모델 패키지에 올바르게 주소를 지정했는지 확인하십시오 sessionFactory
.
<property name="packagesToScan" value="com.mblog.model"></property>
문제가 부분적으로 해결되었습니다. jdbc / resource (DB Derby)를 생성하는 것 외에도 Glassfish 관리 콘솔에서 db 리소스에 대한 JDBC Connection Pool을 생성하고 핑시 확인해야했습니다. 이제 모든 CRUD 작업이 잘 작동합니다. 나는 데이터베이스에서 고객을 적절하게 추가하고 업데이트하고 삭제합니다. 그러나 Glassfish 출력 로그에는 동일한 예외가 있습니다.
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)
em.createQuery 메서드에는 Entity 클래스 이름을 사용해야하고, 엔터티 클래스가없는 네이티브 쿼리에는 em.createNativeQuery 메서드를 사용해야합니다.
엔티티 클래스 사용 :
em.createQuery ( "CUSTOMERV에서 first_name 선택")
엔티티 클래스 또는 기본 쿼리가없는 경우 :
em.createNativeQuery ( "CUSTOMERV c에서 c.first_name 선택")
제 경우에는 스프링 부트 2, 여러 데이터 소스 (기본 및 사용자 지정). entityManager.createQuery
잘못됨 : '엔티티가 매핑되지 않음'
디버그하는 동안 entityManager의 unitName이 잘못되었음을 알았습니다 (사용자 지정이어야하지만 사실은 기본값 임).
@PersistenceContext(unitName = "customer1") // !important,
private EntityManager em;
는 customer1
두 번째 데이터 소스 설정 클래스에서입니다 :
@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();
}
그러면 entityManager가 맞습니다.
그러나 em.persist (entity)가 작동하지 않고 트랜잭션이 작동하지 않습니다.
또 다른 중요한 점은 다음과 같습니다.
@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
두 번째 데이터 소스 구성 클래스에서 가져온 것입니다.
@Bean(name = "customer1TransactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("customer1EntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
두 번째 데이터 소스 구성 클래스 전체는 다음과 같습니다.
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);
}
}
Apache Derby DB에서 테이블 이름을 "user"로 사용하지 마십시오. Apache Derby에서는 예약 된 키워드이지만 MySql에서는 잘 작동하기 때문입니다.
In the Query, you must specify the name of the Entity class that you want to fetch the data from in the FROM clause of the Query.
List<User> users=session.createQuery("from User").list();
Here, User is the name of my Java Entity class(Consider the casing of the name as in Java it matters.)
'Programing' 카테고리의 다른 글
Android에서 채워지지 않은 그림을 그리는 방법은 무엇입니까? (0) | 2020.11.17 |
---|---|
업로드 된 파일을 디렉토리에 저장하기 전에 이름을 바꾸는 방법은 무엇입니까? (0) | 2020.11.17 |
putty를 사용하여 sql.gz 파일을 데이터베이스로 가져오고 삽입하십시오. (0) | 2020.11.16 |
필수 필드에 별표를 표시하도록 LabelFor를 수정하려면 어떻게해야합니까? (0) | 2020.11.16 |
OKHTTP에서 바이너리 파일 다운로드 (0) | 2020.11.16 |