ข้อผิดพลาดไฮเบอร์เนต - QuerySyntaxException: ผู้ใช้ไม่ได้แมป [จากผู้ใช้]


126

ฉันพยายามดึงรายชื่อผู้ใช้ทั้งหมดจากตาราง "ผู้ใช้" และได้รับข้อผิดพลาดต่อไปนี้:

org.hibernate.hql.internal.ast.QuerySyntaxException: users is not mapped [from users]
org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:180)
org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:110)
org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:93)

นี่คือรหัสที่ฉันเขียนเพื่อเพิ่ม / รับผู้ใช้:

public List<User> getUsers() {
    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    session.beginTransaction();
    List<User> result = (List<User>) session.createQuery("from users").list();
    session.getTransaction().commit();
    return result;
}

public void addUser(User user) {
    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    session.beginTransaction();
    session.save(user);
    session.getTransaction().commit();
}

public void addUser(List<User> users) {
    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    session.beginTransaction();
    for (User user : users) {
        session.save(user);
    }
    session.getTransaction().commit();
}

การเพิ่มผู้ใช้ใช้งานได้ แต่เมื่อฉันใช้ฟังก์ชัน getUsers ฉันได้รับข้อผิดพลาดเหล่านี้

นี่คือไฟล์กำหนดค่าไฮเบอร์เนตของฉัน:

<hibernate-configuration>
<session-factory>
    <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
    <property name="connection.username">root</property>
    <property name="connection.password">root</property>
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.default_schema">test</property>
    <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

    <property name="show_sql">true</property>

    <property name="format_sql">true</property>
    <property name="hbm2ddl.auto">create-drop</property>

    <!-- JDBC connection pool (use the built-in) -->
    <property name="connection.pool_size">1</property>
    <property name="current_session_context_class">thread</property>

    <!-- Mapping files will go here.... -->

    <mapping class="model.Company" />
    <mapping class="model.Conference" />
    <mapping class="model.ConferencesParticipants" />
    <mapping class="model.ConferenceParticipantStatus" />
    <mapping class="model.ConferencesUsers" />
    <mapping class="model.Location" />
    <mapping class="model.User" />

</session-factory>

และนี่คือคลาส User ของฉัน:

@Entity
@Table( name = "Users" )
public class User implements Serializable{

    private long userID;
    private int pasportID;
    private Company company; 
    private String name;
    private String email;
    private String phone1;
    private String phone2;
    private String password; //may be null/empty , will be kept hashed
    private boolean isAdmin;
    private Date lastLogin;

    User() {} //not public on purpose!

    public User(int countryID, Company company, String name, String email,
            String phone1, String phone2, String password, boolean isAdmin) {
        this.pasportID = countryID;
        this.company = company;
        this.name = name;
        this.email = email;
        this.phone1 = phone1;
        this.phone2 = phone2;
        this.password = password;
        this.isAdmin = isAdmin;
    }

    @Id
    @GeneratedValue(generator="increment")
    @GenericGenerator(name="increment", strategy = "increment")
    public long getUserID() {
        return userID;
    }
    public void setUserID(long userID) {
        this.userID = userID;
    }
    ...    
}

มีความคิดว่าทำไมฉันจึงได้รับข้อผิดพลาดนี้


1
เกี่ยวข้องกับ: stackoverflow.com/questions/14446048/…
Grey

คำตอบ:


297

ใน HQL คุณควรใช้ชื่อคลาส javaและชื่อคุณสมบัติของการแมป@Entityแทนชื่อตารางและชื่อคอลัมน์จริงดังนั้น HQL ควรเป็น:

List<User> result = session.createQuery("from User", User.class).getResultList();

อัปเดต: เพื่อให้แม่นยำยิ่งขึ้นคุณควรใช้ชื่อเอนทิตีที่กำหนดค่า@Entityเพื่ออ้างถึง "ตาราง" ซึ่งเป็นค่าเริ่มต้นของชื่อคลาส java ที่แมปหากคุณไม่ได้ตั้งค่าไว้อย่างชัดเจน

(ปล. เป็น@javax.persistence.Entityแต่ไม่ใช่@org.hibernate.annotations.Entity)


10
จริงๆแล้วนี่เป็นกรณีที่ละเอียดอ่อนด้วยซ้ำ ดังนั้น "จากผู้ใช้" จะส่งผลให้ยกเว้นเดียวกัน
Tobi

3
เป็นส่วนหนึ่งของคำตอบ แต่ในการแก้ไขข้อผิดพลาดฉันต้องใช้เส้นทางวัตถุแบบเต็มเช่นนี้: [... ]. createQuery ("from gcv.metier.User as u where u.username =?")
Raphael

ฉันยังต้องใช้เส้นทางทั้งหมดบางที JPA อาจมีปัญหากับคำว่า "User"? ฉันเดาว่ามันเป็นคำสงวนในการใช้งาน DB บางส่วน ในความเป็นจริงปัญหานี้เกิดขึ้นเมื่อฉันเปลี่ยนชื่อตาราง db นั้นจากผู้ใช้เป็นthe_user (ส่วนหนึ่งของการแก้ไขปัญหาอื่น) ก่อนที่ JPA จะใช้ได้
Michael Coxon

1
คุณช่วยปรับปรุงรายการ () เป็น getResultList () ได้ไหมเนื่องจากรายการเดิมเลิกใช้แล้ว
Durja Arai

31

ตัวอย่างเช่นชื่อคลาส bean ของคุณคือUserDetails

Query query = entityManager. createQuery("Select UserName from **UserDetails** "); 

คุณไม่ได้ระบุชื่อตารางของคุณบน Db คุณให้ชื่อชั้นของถั่ว


12

เพียงเพื่อแบ่งปันการค้นพบของฉัน ฉันยังคงได้รับข้อผิดพลาดเดิมแม้ว่าข้อความค้นหาจะกำหนดเป้าหมายชื่อคลาสที่ถูกต้อง หลังจากนั้นฉันก็รู้ว่าฉันกำลังนำเข้าคลาสเอนทิตีจากแพ็คเกจที่ไม่ถูกต้อง

ปัญหาได้รับการแก้ไขหลังจากฉันเปลี่ยนบรรทัดการนำเข้าจาก:

import org.hibernate.annotations.Entity;

ถึง

import javax.persistence.Entity;

ตอนนี้สิ่งนี้ช่วยฉันได้จริง
Anirudh

9

เพิ่ม@TABLE(name = "TABLE_NAME")คำอธิบายประกอบและแก้ไข ตรวจสอบคำอธิบายประกอบและไฟล์ hibernate.cfg.xml นี่คือไฟล์เอนทิตีตัวอย่างที่ใช้งานได้:

import javax.persistence.*;

@Entity
@Table(name = "VENDOR")
public class Vendor {

    //~ --- [INSTANCE FIELDS] ------------------------------------------------------------------------------------------
    private int    id;
    private String name;

    //~ --- [METHODS] --------------------------------------------------------------------------------------------------
    @Override
    public boolean equals(final Object o) {    
        if (this == o) {
            return true;
        }

        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        final Vendor vendor = (Vendor) o;

        if (id != vendor.id) {
            return false;
        }

        if (name != null ? !name.equals(vendor.name) : vendor.name != null) {
            return false;
        }

        return true;
    }

    //~ ----------------------------------------------------------------------------------------------------------------
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    public int getId() {
        return id;
    }

    @Basic
    @Column(name = "NAME")
    public String getName() {

        return name;
    }

    public void setId(final int id) {
        this.id = id;
    }

    public void setName(final String name) {    
        this.name = name;
    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }
}

8

มีความเป็นไปได้ที่คุณลืมเพิ่มการแมปสำหรับเอนทิตีที่สร้างขึ้นhibernate.cfg.xmlข้อผิดพลาดเดียวกัน


ฉันลืมเพิ่มคลาส POJO ใน hibernate.cfg.xml ด้วย
Chinmoy

6

org.hibernate.hql.internal.ast.QuerySyntaxException: users is not mapped [from users]

สิ่งนี้บ่งชี้ว่าไฮเบอร์เนตไม่รู้จักUserเอนทิตีในฐานะ "ผู้ใช้"

@javax.persistence.Entity
@javax.persistence.Table(name = "Users")
public class User {

@Tableคำอธิบายประกอบชุดโต๊ะชื่อเป็น "ผู้ใช้" แต่ชื่อนิติบุคคลยังคงเป็นที่กล่าวถึงใน HQL เป็น "ผู้ใช้"

หากต้องการเปลี่ยนทั้งสองอย่างคุณควรตั้งชื่อเอนทิตี:

// this sets the name of the table and the name of the entity
@javax.persistence.Entity(name = "Users")
public class User implements Serializable{

ดูคำตอบของฉันที่นี่สำหรับข้อมูลเพิ่มเติม: ข้อผิดพลาดที่ไม่ได้ทำแผนที่ไฮเบอร์เนต


5

ตรวจสอบให้แน่ใจด้วยว่าได้ตั้งค่าคุณสมบัติต่อไปนี้ในการกำหนดค่า hibernate bean

<property name="packagesToScan" value="yourpackage" />

สิ่งนี้จะบอกฤดูใบไม้ผลิและจำศีลว่าจะค้นหาคลาสโดเมนของคุณที่มีคำอธิบายประกอบเป็นเอนทิตีได้ที่ไหน


5

การติดตั้ง MySQL บน Linux บางอย่างต้องใช้ตัวพิมพ์เล็กและใหญ่ nativeQueryรอบการทำงานคือการใช้

@Query(value = 'select ID, CLUMN2, CLUMN3 FROM VENDOR c where c.ID = :ID', nativeQuery = true)

1
แน่ใจหรือว่า "MySQL ที่ใช้ Linux" มีบทบาทที่นี่
asgs

3

ฉันยังนำเข้าเอนทิตีที่ไม่ถูกต้องimport org.hibernate.annotations.Entity; ซึ่งควรนำเข้าjavax.persistence.Entity;


3

ตรวจสอบด้วยว่าคุณได้เพิ่มคลาสที่มีคำอธิบายประกอบโดยใช้:

new Configuration().configure("configuration file path").addAnnotatedClass(User.class)

นั่นทำให้ฉันเสียเวลาไปกับการเพิ่มตารางใหม่ในฐานข้อมูลโดยใช้ไฮเบอร์เนต


2

ฉันได้รับข้อผิดพลาดเดียวกันในขณะที่ Spring ที่มีโหมดไฮเบอร์เนต .. ฉันใช้ "ผู้ใช้" ในตัวพิมพ์เล็กในcreateQueryคำสั่งของฉันและชั้นเรียนของฉันคือ User .. ดังนั้นจึงเปลี่ยนเป็น User ในการสืบค้นและปัญหาได้รับการแก้ไข

สอบถามก่อน:

Query query= em.createQuery("select u from user u where u.username=:usr AND u.password=:pass",User.class);

ค้นหาหลังจาก:

Query query= em.createQuery("select u from User u where u.username=:usr AND u.password=:pass",User.class);

1

ฉันพบปัญหานี้เมื่อฉันเปลี่ยนไลบรารี hibernate-core เก่าด้วย hibernate-core-5.2.12 อย่างไรก็ตามการกำหนดค่าทั้งหมดของฉันก็โอเค และฉันแก้ไขปัญหานี้ด้วยการสร้าง sessionfactory ด้วยวิธีนี้:

private static SessionFactory buildsSessionFactory() {
    try {
        if (sessionFactory == null) {
            StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
                    .configure("/hibernate.cfg.xml").build();
            Metadata metaData = new MetadataSources(standardRegistry)
                    .getMetadataBuilder().build();
            sessionFactory = metaData.getSessionFactoryBuilder().build();
        }
        return sessionFactory;
    } catch (Throwable th) {

        System.err.println("Enitial SessionFactory creation failed" + th);

        throw new ExceptionInInitializerError(th);

    }
}

หวังว่ามันจะช่วยใครบางคน


1

ฉันแนะนำรูปแบบนี้:

@Entity(name = User.PERSISTANCE_NAME)
@Table(name = User.PERSISTANCE_NAME )
public class User {    
    static final String PERSISTANCE_NAME = "USER";

    // Column definitions here

}

0

ในแบบสอบถามของคุณคุณต้องใช้ชื่อคลาส (ผู้ใช้) ไม่ใช่ชื่อตาราง (ผู้ใช้) ดังนั้นคำค้นหาของคุณจึงเป็น "จากผู้ใช้"


0

คุณต้องพิมพ์ชื่อเดียวกันในแบบสอบถามที่เลือกเป็นเอนทิตีหรือคลาสของคุณ (พิจารณาตัวพิมพ์เล็กและใหญ่) เช่นเลือกผู้ใช้จาก className / Entity Name user;


0

กับ org.hibernate.hql.internal.ast.QuerySyntaxException: users is not mapped [from users]คุณกำลังพยายามที่จะเลือกจากusersตาราง แต่คุณกำลัง annotating @Table( name = "Users" )ระดับของคุณด้วย ดังนั้นใช้usersหรือUsers.


0

หากคุณใช้การกำหนดค่า xml คุณจะต้องมีสิ่งต่อไปนี้ในไฟล์ applicationContext.xml:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" lazy-init="default" autowire="default" dependency-check="default">
<property name="dataSource">
  <ref bean="dataSource" />
</property>
<property name="annotatedClasses">
  <list>
    <value>org.browsexml.timesheetjob.model.PositionCode</value>
  </list>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.