Mam przykładową aplikację internetową Hibernate 4.3.5 + bazę danych Derby 10.10.1.1+ Glassfish4.0 z IDE NetBeans 8.0Beta.
Mam kolejny wyjątek:
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
Formularz z 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>
java
hibernate
derby
glassfish-4
Vlad Dobrydin
źródło
źródło
w kwerendzie HQL nie wpisuj nazwy tabeli , wpisz nazwę klasy jednostki w zapytaniu, np
String s = "from Entity_class name"; query qry = session.createUqery(s);
źródło
W moim przypadku po prostu zapomniałem dodać
nativeQuery = true
@Query( value = "some sql query ...", nativeQuery = true)
Do rozruchu sprężynowego ze sprężyną danych JPA
źródło
Plik hibernate.cfg.xml powinien mieć odwzorowanie dla tabel jak poniżej. Sprawdź, czy brakuje go w pliku.
...... <hibernate-configuration> ...... ...... <session-factory> ...... <mapping class="com.test.bean.dbBean.testTableHibernate"/> ...... </session-factory> </hibernate-configuration> .....
źródło
Jeśli używasz adnotacji JPA do tworzenia jednostek, a następnie upewnij się, że nazwa tabeli jest mapowana wraz z adnotacją @Table zamiast @Entity.
Nieprawidłowo zmapowane:
@Entity(name="DB_TABLE_NAME") public class DbTableName implements Serializable { .... .... }
Prawidłowo zmapowany obiekt:
@Entity @Table(name="DB_TABLE_NAME") public class DbTableName implements Serializable { .... .... }
źródło
Może to sprawi, że będzie to bardziej zrozumiałe i oczywiście ma to również sens.
@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 { ... }
źródło
Żadne inne rozwiązanie nie działało dla mnie.
Nawet jeśli nie uważam, że to najlepsza praktyka, musiałem dodać to do kodu w ten sposób
configuration.addAnnotatedClass(com.myOrg.entities.Person.class);
tutaj
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; }
źródło
Jest jeszcze jedna szansa na uzyskanie tego wyjątku, nawet jeśli użyliśmy nazwy klasy, tj. Jeśli mamy dwie klasy o tej samej nazwie w różnych pakietach. rozwiążemy ten problem.
Myślę, że hibernacja może spowodować niejednoznaczność i zgłosić ten wyjątek, więc rozwiązaniem jest użycie pełnej nazwy kwalifikowanej (takiej jak com.test.Customerv )
Dodałem tę odpowiedź, która pomoże w scenariuszu, o którym wspomniałem. Ten sam scenariusz utknąłem na jakiś czas.
źródło
Ja też napotkałem podobny problem, kiedy zacząłem pracować nad Hibernate. Podsumowując, mogę powiedzieć, że w createQuery należy podać nazwę klasy jednostki, a nie nazwę tabeli, na którą mapowana jest jednostka.
źródło
Oznacza to, że twoja tabela nie jest zmapowana do JPA. Albo nazwa tabeli jest nieprawidłowa (może być rozróżniana wielkość liter), albo musisz umieścić wpis w pliku XML.
Miłego kodowania :)
źródło
Inne osoby, które używają klas mapujących dla Hibernate, upewnij się, że poprawnie zaadresowały model pakietu w
sessionFactory
deklaracji beana w dalszej części:<property name="packagesToScan" value="com.mblog.model"></property>
źródło
packages-to-scan
w moimapplication.yml
pliku konfiguracyjnym.Jeśli przypadkiem używasz javy do konfiguracji, być może będziesz musiał sprawdzić poniższą
bean
deklarację, jeśli masz zmiany na poziomie pakietu. Np .:com.abc.spring
pakiet zmieniony nacom.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(); }
źródło
W moim przypadku: rozruch sprężynowy 2, wiele źródeł danych (domyślne i niestandardowe).
entityManager.createQuery
pójść źle: „obiekt nie jest mapowany”podczas debugowania stwierdzam, że nazwa unitName w entityManager jest błędna (powinna być niestandardowa, ale fakt jest domyślny) we właściwy sposób:
@PersistenceContext(unitName = "customer1") // !important, private EntityManager em;
customer1
jest od drugiej klasy DataSource config:@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(); }
Zatem entityManager ma rację.
Ale em.persist (entity) nie działa, a transakcja nie działa.
Kolejna ważna kwestia to:
@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
pochodzi z drugiej klasy konfiguracji źródła danych:@Bean(name = "customer1TransactionManager") public PlatformTransactionManager transactionManager( @Qualifier("customer1EntityManagerFactory") EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); }
Cała druga klasa konfiguracji źródła danych to:
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); } }
źródło
Problem został częściowo rozwiązany. Oprócz tworzenia jdbc / resource (DB Derby) musiałem utworzyć pulę połączeń JDBC dla zasobu db w konsoli administracyjnej Glassfish i sprawdzić ją podczas pingowania. Teraz wszystkie operacje CRUD działają dobrze. Sprawdzam, poprawnie wpisuję klienta do bazy danych, aktualizuję i usuwam. Ale w dzienniku wyjściowym Glassfish mają ten sam wyjątek:
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)
źródło
Powinien używać nazwy klasy jednostki dla metody em.createQuery lub metody em.createNativeQuery dla zapytania natywnego bez klasy jednostki
Z klasą Entity:
em.createQuery ("wybierz imię z CUSTOMERV")
Bez klasy jednostki lub zapytania natywnego:
em.createNativeQuery ("wybierz c.first_name z CUSTOMERV c")
źródło
W Apache Derby DB nie używaj nazw tabel jako „użytkowników”, ponieważ są one zarezerwowanymi słowami kluczowymi w Apache Derby, ale będą działać dobrze w MySql.
W zapytaniu musisz określić nazwę klasy Entity, z której chcesz pobrać dane w klauzuli FROM zapytania.
List<User> users=session.createQuery("from User").list();
Tutaj User jest nazwą mojej klasy Java Entity (Rozważ wielkość liter nazwy, ponieważ w Javie ma to znaczenie).
źródło
Inne rozwiązanie, które zadziałało:
Obiekt dostępu do danych, który faktycznie zgłosił ten wyjątek, to
public List<Foo> findAll() { return sessionFactory.getCurrentSession().createQuery("from foo").list(); }
Błąd, który popełniłem w powyższym fragmencie, polega na tym, że użyłem nazwy tabeli foo wewnątrz createQuery. Zamiast tego musiałem użyć Foo, rzeczywistej nazwy klasy.
public List<Foo> findAll() { return sessionFactory.getCurrentSession().createQuery("from Foo").list();
Dzięki temu blogowi: https://www.arundhaj.com/blog/querysyntaxexception-not-mapped.html
źródło
Inne osoby, które używają klas mapujących dla Hibernate, upewnij się, że poprawnie zaadresowały pakiet modelowy w deklaracji beana sessionFactory w dalszej części:
public List<Book> list() { List<Book> list=SessionFactory.getCurrentSession().createQuery("from book").list(); return list; }
Błąd, który popełniłem w powyższym fragmencie, polega na tym, że użyłem nazwy tabeli foo wewnątrz createQuery. Zamiast tego musiałem użyć Foo, rzeczywistej nazwy klasy.
public List<Book> list() { List<Book> list=SessionFactory.getCurrentSession().createQuery("from Book").list(); return list; }
źródło
dodaj parametr nativeQuery = true
np .: @Query (wartość = "Aktualizuj zestaw użytkownika nazwa_użytkownika =: nazwa_użytkownika, hasło =: hasło gdzie identyfikator_użytkownika =: identyfikator_użytkownika", nativeQuery = true)
źródło