java.lang.IllegalArgumentException:找不到命名查询。(实体管理器未创建NamedQuery)

我正在使用hibernate 4.1.5.Final和Spring 3.1.2 Release以及Jboss 7.1。 我已经使用@NamedQuery注释在类中编写了所有命名查询,但实体管理器没有创建命名查询。 我发布了stacktrace和context.xml

09:58:49,695 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) java.lang.IllegalArgumentException: Named query not found: validateLoginHash 09:58:49,770 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at org.hibernate.ejb.AbstractEntityManagerImpl.createNamedQuery(AbstractEntityManagerImpl.java:642) 09:58:49,772 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at sun.reflect.GeneratedMethodAccessor14.invoke(Unknown Source) 09:58:49,774 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 09:58:49,777 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at java.lang.reflect.Method.invoke(Method.java:597) 09:58:49,779 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365) 09:58:49,782 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at $Proxy30.createNamedQuery(Unknown Source) 09:58:49,784 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at sun.reflect.GeneratedMethodAccessor14.invoke(Unknown Source) 09:58:49,785 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 09:58:49,788 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at java.lang.reflect.Method.invoke(Method.java:597) 09:58:49,790 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240) 09:58:49,793 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at $Proxy30.createNamedQuery(Unknown Source) 

applicationContext.xml中

             <!--  -->             

JPA-的persistence.xml

   org.hibernate.ejb.HibernatePersistence java:jboss/datasources/MySqlDS <!--  --> <!--  --> <!--  -->   

DBNamedQuery.java

 @Entity @NamedQueries( { @NamedQuery(name = ... , query = ... ), @NamedQuery(name = ..., query = ...), .....More named queries }) public class DBNamedQuery { } 

 I have written all named queries in a class with @NamedQuery annotation 

您没有清楚地提到您在上述声明中提到的类的类型? 您需要在Entity类中编写命名查询(使用@Entity批注注释的类)。

更新:我现在对你的类DBNamedQuery感到困惑。 您说您正在使用一个类来放置所有命名查询。 我的理解是您正在使用此类为应用程序的所有实体编写命名查询。 如果这是正确的,你如何在类DBNamedQuery上使用@Entity注释,因为它不是真正的jpa实体?

包含@NamedQuery注释的类应该是一个托管实体。 我怀疑你的类DBNamedQuery不是。

要确定问题,我建议检查日志,如果这是一个manged实体。 如果你不能这样做,那么EntityManger会给你和API来检查在运行时contains(java.lang.Object entity)

在相关的说明中,如果您使用的是注释,那么JPA Named Queries是jpa实体的一部分。 使用xml可以灵活地存储在单独的文件中。

嗨我得到你的问题而不是创建一个类为什么不为你的命名查询创建一个xml文件,如Queries.hbm.xml,如下

     from User u where u.username = ?  

将此xml文件保存在resources文件夹中,并在applicationContext-enterprise-config.xml文件中将其写入如下

   /resources/hbms/Queries.hbm.xml   

所以它会正常工作。

编辑好它取决于你在DAO层中如何调用它。 你必须像=>一样打电话

 public int executeNamedQuery(String namedQuery, String namedParams[], Object params[]) throws DatabaseException { int result = 0; Session session = getSession(); final String methodName = "executeNamedQuery"; try { session.beginTransaction(); Query q = session.getNamedQuery(namedQuery); if (namedParams != null) { for (int i = 0; i < namedParams.length; i++) { q.setParameter(namedParams[i], params[i]); } } result = q.executeUpdate(); session.getTransaction().commit(); logger.debug("{} :: {} = {}", new Object[] { methodName, "No. of objects affected", result }); } catch (HibernateException e) { session.getTransaction().rollback(); final String message = "Couldn't execute the named query " + namedQuery; logger.error("{} :: {}", new Object[] { methodName, message, e }); throw new DatabaseException(getClass(), methodName, message, e); } finally { closeSession(); } return result; } 

注意:1)namedQuery表示Queries.hbm.xml文件中的查询名称。 2)namedParams []表示Query的参数名称。 3)参数表示参数的值。

检查您的实体类DBNamedQuery是否在ApplicationContext.xml文件中配置的com.project.entities包中

我认为这是因为名字未命中。 在@NamedQuery中声明的名称与调用该查询的名称不匹配。

例如

 @NamedQuery(name = "AAAA", query = ... ) //must be same the name which call that query public void some() { Query q = em.createNamedQuery("AAAA"); } 

在persistence.xml中添加注释扫描为我解决了这个问题

  

即使我尝试在我的实体管理器中提供包扫描,如下所示也没有工作

  @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(getDataSource()); //em.setPackagesToScan("com.comp.proj.domain"); em.setPersistenceUnitName(PERSISTENCE_UNIT_NAME); em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); return em; }