Błąd hibernacji - QuerySyntaxException: użytkownicy nie są zamapowani [od użytkowników]

126

Próbuję uzyskać listę wszystkich użytkowników z tabeli „użytkownicy” i otrzymuję następujący błąd:

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)

Oto kod, który napisałem, aby dodać / pobrać użytkowników:

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();
}

Dodawanie użytkowników działa, ale kiedy używam funkcji getUsers, pojawia się ten błąd.

To jest mój plik konfiguracyjny hibernacji:

<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>

a to jest moja klasa użytkownika:

@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;
    }
    ...    
}

Masz jakiś pomysł, dlaczego otrzymuję ten błąd?

niebieski
źródło

Odpowiedzi:

297

W języku HQL należy użyć nazwy klasy java i nazwy właściwości mapowanej @Entityzamiast rzeczywistej nazwy tabeli i nazwy kolumny, więc HQL powinien być:

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

Aktualizacja: Aby być bardziej precyzyjnym, należy użyć nazwy jednostki skonfigurowanej w programie, @Entityaby odwołać się do „tabeli”, która domyślnie jest niekwalifikowaną nazwą zmapowanej klasy Java, jeśli nie ustawisz jej jawnie.

(PS Tak, @javax.persistence.Entityale nie @org.hibernate.annotations.Entity)

Ken Chan
źródło
10
W rzeczywistości rozróżnia się nawet wielkość liter. więc „od użytkownika” spowodowałoby ten sam wyjątek
tObi,
3
Jest to część odpowiedzi, ale aby rozwiązać błąd, musiałem użyć pełnej ścieżki obiektu, takiej jak ta: [...]. CreateQuery ("from gcv.metier.User as u, gdzie u.username =?")
Raphael
Musiałem też użyć całej ścieżki, może JPA ma problem ze słowem „Użytkownik”? Myślę, że jest to słowo zastrzeżone w kilku implementacjach DB. W rzeczywistości ten problem pojawił się dopiero ode mnie, kiedy zmieniłem nazwę tej tabeli db z user na the_user (część rozwiązywania innego problemu), zanim JPA było w porządku.
Michael Coxon
1
czy możesz zaktualizować listę () do getResultList (), ponieważ ta pierwsza jest przestarzała?
Durja Arai
31

Na przykład: nazwa Twojej klasy bean to UserDetails

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

Nie podajesz nazwy swojego stołu na Db. podajesz nazwę klasy fasola .

Kumaresan Perumal
źródło
12

Chcę tylko podzielić się moim odkryciem. Nadal pojawia się ten sam błąd, nawet jeśli zapytanie dotyczyło poprawnej nazwy klasy. Później zdałem sobie sprawę, że importuję klasę Entity z niewłaściwego pakietu.

Problem został rozwiązany po zmianie linii importu z:

import org.hibernate.annotations.Entity;

do

import javax.persistence.Entity;
Iwan Satria
źródło
Teraz to mnie uratowało.
Anirudh
9

Dodano @TABLE(name = "TABLE_NAME")adnotację i naprawiono. Sprawdź swoje adnotacje i plik hibernate.cfg.xml. Oto przykładowy plik encji, który działa:

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;
    }
}
Fırat KÜÇÜK
źródło
8

Istnieje możliwość, że zapomniałeś dodać mapowanie dla utworzonej jednostki do tego hibernate.cfg.xmlsamego błędu.

Augustas
źródło
Ja też zapomniałem dodać klasę POJO do hibernate.cfg.xml.
Chinmoy,
6

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

Oznacza to, że hibernacja nie rozpoznaje Userjednostki jako „użytkowników”.

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

@TableAdnotacja ustawia stół nazwy być „Użytkownicy”, ale nazwa jest nadal żywa, o których mowa w HQL jako „Użytkownik”.

Aby zmienić oba, należy ustawić nazwę podmiotu:

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

Zobacz moją odpowiedź tutaj, aby uzyskać więcej informacji: Błąd mapowania tabeli hibernacji

Szary
źródło
5

Upewnij się również, że w konfiguracji ziaren hibernacji jest ustawiona następująca właściwość:

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

To mówi wiosnie i hibernacji, gdzie znaleźć klasy domeny oznaczone jako jednostki.

jrreid
źródło
5

Niektóre instalacje MySQL oparte na systemie Linux wymagają rozróżniania wielkości liter. Obejście polega na zastosowaniu nativeQuery.

@Query(value = 'select ID, CLUMN2, CLUMN3 FROM VENDOR c where c.ID = :ID', nativeQuery = true)
Rajkumar
źródło
1
czy na pewno „bazujący na Linuksie MySQL” ma tutaj rolę?
asgs
3

Również importowałem niewłaściwą jednostkę. import org.hibernate.annotations.Entity; Powinien to być importjavax.persistence.Entity;

Ratheesh K.
źródło
3

Sprawdź również, czy dodałeś klasę z adnotacjami, używając:

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

To zawsze marnowało mój czas podczas dodawania nowej tabeli do bazy danych za pomocą Hibernate.

Gherbi Hicham
źródło
2

createQueryOtrzymałem ten sam błąd, gdy Spring z hibernacją .. Użyłem "user" w mojej instrukcji, a moja klasa to User ... Więc zmieniłem ją na User w moim zapytaniu i problem został rozwiązany.

Zapytanie przed:

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

Zapytanie po:

Query query= em.createQuery("select u from User u where u.username=:usr AND u.password=:pass",User.class);
Himanshu Shukla
źródło
1

Wystąpił ten problem, gdy zastąpiłem starą bibliotekę hibernate-core na hibernate-core-5.2.12. Jednak cała moja konfiguracja była w porządku. I naprawiłem ten problem, tworząc sessionfactory w ten sposób:

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);

    }
}

Mam nadzieję, że to komuś pomoże

Lakhan Sharma
źródło
1

Polecam ten wzór:

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

    // Column definitions here

}
Jonas Gröger
źródło
0

W swoim zapytaniu musisz użyć nazwy klasy (użytkownik), a nie nazwy tabeli (użytkownicy), więc twoje zapytanie jest „od użytkownika”

sami gharbi
źródło
0

W zapytaniu wybierającym należy wpisać tę samą nazwę, co jednostka lub klasa (z uwzględnieniem wielkości liter). tj. wybierz użytkownika z className / Entity Name user;

Vipul Thakur
źródło
0

z org.hibernate.hql.internal.ast.QuerySyntaxException: users is not mapped [from users], próbujesz wybrać z userstabeli. Ale dodajesz do swojej klasy adnotację @Table( name = "Users" ). Więc albo użyj users, albo Users.

zak zak
źródło
0

Jeśli używasz konfiguracji XML, będziesz potrzebować czegoś podobnego do następującego w pliku 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>
Geoffrey Ritchey
źródło