web-dev-qa-db-fra.com

Mappage JPA: "QuerySyntaxException: foobar n'est pas mappé ..."

J'ai joué avec un exemple très simple d'APP et j'essaie de le modifier pour en faire une base de données existante. Mais je ne peux pas dépasser cette erreur. (Ci-dessous.) Il doit simplement s'agir d'une chose simple que je ne vois pas.

org.hibernate.hql.internal.ast.QuerySyntaxException: FooBar is not mapped [SELECT r FROM FooBar r]
  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)

Dans la classe DocumentManager ci-dessous (une simple servlet, car c'est mon objectif cible), fait deux choses:

  1. insérer une ligne
  2. renvoyer toutes les lignes

L'insertion fonctionne parfaitement - tout y est bon. Le problème est avec la récupération. J'ai essayé toutes sortes de valeurs pour le Query q = entityManager.createQuery paramètres, mais pas de chance, et j'ai essayé diversement plus d'expliquer des annotations de la classe (comme les types de colonne), le tout sans succès.

S'il te plaît, sauve-moi de moi-même. Je suis certain que c'est quelque chose de petit. Mon manque d'expérience avec JPA m'empêche d'aller plus loin.

Mon fichier ./src/ch/geekomatic/jpa/FooBar.Java:

@Entity
@Table( name = "foobar" )
public class FooBar {
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @Column(name="id")
    private int id;

    @Column(name="rcpt_who")
    private String rcpt_who;

    @Column(name="rcpt_what")
    private String rcpt_what;

    @Column(name="rcpt_where")
    private String rcpt_where;

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

    public String getRcpt_who() {
        return rcpt_who;
    }
    public void setRcpt_who(String rcpt_who) {
        this.rcpt_who = rcpt_who;
    }

    //snip...the other getters/setters are here
}

Ma classe ./src/ch/geekomatic/jpa/DocumentManager.Java

public class DocumentManager extends HttpServlet {
    private EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory( "ch.geekomatic.jpa" );

    protected void tearDown() throws Exception {
        entityManagerFactory.close();
    }

   @Override
   public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
       FooBar document = new FooBar();
       document.setRcpt_what("my what");
       document.setRcpt_who("my who");

       persist(document);

       retrieveAll(response);
   }

   public void persist(FooBar document) {
       EntityManager entityManager = entityManagerFactory.createEntityManager();
       entityManager.getTransaction().begin();
       entityManager.persist( document );
       entityManager.getTransaction().commit();
       entityManager.close();
   }

    public void retrieveAll(HttpServletResponse response) throws IOException {
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        entityManager.getTransaction().begin();

        //  *** PROBLEM LINE ***
        Query q = entityManager.createQuery( "SELECT r FROM foobar r", FooBar.class );
        List<FooBar> result = q.getResultList();

        for ( FooBar doc : result ) {
            response.getOutputStream().write(event.toString().getBytes());
            System.out.println( "Document " + doc.getId()  );
        }
        entityManager.getTransaction().commit();
        entityManager.close();
    }
}

Le fichier {Tomcat-home} /webapps/ROOT/WEB-INF/classes/METE-INF/persistance.xml

<persistence xmlns="http://Java.Sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://Java.Sun.com/xml/ns/persistence http://Java.Sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">

<persistence-unit name="ch.geekomatic.jpa">
    <description>test stuff for dc</description>

    <class>ch.geekomatic.jpa.FooBar</class>

    <properties>
        <property name="javax.persistence.jdbc.driver"   value="com.mysql.jdbc.Driver" />
        <property name="javax.persistence.jdbc.url"      value="jdbc:mysql://svr:3306/test" />
        <property name="javax.persistence.jdbc.user"     value="wafflesAreYummie" />
        <property name="javax.persistence.jdbc.password" value="poniesRock" />

        <property name="hibernate.show_sql"     value="true" />
        <property name="hibernate.hbm2ddl.auto" value="create" />
    </properties>

</persistence-unit>
</persistence>

Description de la table MySQL:

mysql> describe foobar;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| rcpt_what  | varchar(255) | YES  |     | NULL    |                |
| rcpt_where | varchar(255) | YES  |     | NULL    |                |
| rcpt_who   | varchar(255) | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
66
Stu Thompson

JPQL principalement ne respecte pas la casse. Une des choses sensibles à la casse est Java. Modifiez votre requête en:

"SELECT r FROM FooBar r"
159
Chris

Il existe également une autre source possible de cette erreur. Dans certains conteneurs J2EE/web (d'après mon expérience sous Jboss 7.x et Tomcat 7.x) Vous devez ajouter chaque classe que vous souhaitez utiliser en tant qu'entité d'hibernation dans le fichier persistance .xml as

<class>com.yourCompanyName.WhateverEntityClass</class>

Dans le cas de jboss, cela concerne toutes les classes d’entités (local - c’est-à-dire dans le projet que vous développez ou dans une bibliothèque). Dans le cas de Tomcat 7.x, cela ne concerne que les classes d'entités dans les bibliothèques.

14
user2463675

Vous avez déclaré votre classe comme:

@Table( name = "foobar" )
public class FooBar {

Vous devez écrire le nom de la classe pour la recherche.
de FooBar

5
Arnab Chakraborty